mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-31 22:59:54 +02:00
Artifact instances are now owned solely by CMap
This commit is contained in:
parent
797646cc05
commit
2ca1748e96
@ -223,49 +223,6 @@ DLL_LINKAGE std::vector<const CArtifact*> ArtifactUtils::assemblyPossibilities(
|
||||
return arts;
|
||||
}
|
||||
|
||||
DLL_LINKAGE CArtifactInstance * ArtifactUtils::createScroll(const SpellID & spellId)
|
||||
{
|
||||
return ArtifactUtils::createArtifact(ArtifactID::SPELL_SCROLL, spellId);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
auto * artInst = new CArtifactInstance(art);
|
||||
if(art->isCombined() && !art->isFused())
|
||||
{
|
||||
for(const auto & part : art->getConstituents())
|
||||
artInst->addPart(createArtInst(part), ArtifactPosition::PRE_FIRST);
|
||||
}
|
||||
if(art->isGrowing())
|
||||
{
|
||||
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
|
||||
{
|
||||
return new CArtifactInstance(); // random, empty
|
||||
}
|
||||
}
|
||||
|
||||
DLL_LINKAGE void ArtifactUtils::insertScrrollSpellName(std::string & description, const SpellID & sid)
|
||||
{
|
||||
// We expect scroll description to be like this: This scroll contains the [spell name] spell which is added
|
||||
|
@ -39,8 +39,6 @@ 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 & spellId);
|
||||
DLL_LINKAGE CArtifactInstance * createArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
|
||||
DLL_LINKAGE void insertScrrollSpellName(std::string & description, const SpellID & sid);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "json/JsonBonus.h"
|
||||
#include "mapObjectConstructors/AObjectTypeHandler.h"
|
||||
#include "mapObjectConstructors/CObjectClassesHandler.h"
|
||||
#include "mapping/CMap.h"
|
||||
#include "serializer/JsonSerializeFormat.h"
|
||||
#include "texts/CGeneralTextHandler.h"
|
||||
#include "texts/CLegacyConfigParser.h"
|
||||
@ -705,20 +706,28 @@ void CArtHandler::afterLoadFinalization()
|
||||
}
|
||||
art->nodeHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, bool excludeLocked) const
|
||||
const CArtifactInstance * CArtifactSet::getArt(const ArtifactPosition & pos, bool excludeLocked) const
|
||||
{
|
||||
if(const ArtSlotInfo * si = getSlot(pos))
|
||||
{
|
||||
if(si->artifact && (!excludeLocked || !si->locked))
|
||||
return si->artifact;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ArtifactInstanceID CArtifactSet::getArtID(const ArtifactPosition & pos, bool excludeLocked) const
|
||||
{
|
||||
if(const ArtSlotInfo * si = getSlot(pos))
|
||||
{
|
||||
if(si->artifact && (!excludeLocked || !si->locked))
|
||||
return si->artifact->getId();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
ArtifactPosition CArtifactSet::getArtPos(const ArtifactID & aid, bool onlyWorn, bool allowLocked) const
|
||||
{
|
||||
for(const auto & [slot, slotInfo] : artifactsWorn)
|
||||
@ -781,10 +790,10 @@ bool CArtifactSet::hasArt(const ArtifactID & aid, bool onlyWorn, bool searchComb
|
||||
return false;
|
||||
}
|
||||
|
||||
CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition & slot, CArtifactInstance * art)
|
||||
CArtifactSet::ArtPlacementMap CArtifactSet::putArtifact(const ArtifactPosition & slot, const CArtifactInstance * art)
|
||||
{
|
||||
ArtPlacementMap resArtPlacement;
|
||||
const auto putToSlot = [this](const ArtifactPosition & targetSlot, CArtifactInstance * targetArt, bool locked)
|
||||
const auto putToSlot = [this](const ArtifactPosition & targetSlot, const CArtifactInstance * targetArt, bool locked)
|
||||
{
|
||||
ArtSlotInfo * slotInfo;
|
||||
if(targetSlot == ArtifactPosition::TRANSITION_POS)
|
||||
@ -939,10 +948,10 @@ void CArtifactSet::artDeserializationFix(CBonusSystemNode *node)
|
||||
{
|
||||
for(auto & elem : artifactsWorn)
|
||||
if(elem.second.artifact && !elem.second.locked)
|
||||
node->attachTo(*elem.second.artifact);
|
||||
node->attachToSource(*elem.second.artifact);
|
||||
}
|
||||
|
||||
void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName)
|
||||
void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName, CMap * map)
|
||||
{
|
||||
//todo: creature and commander artifacts
|
||||
if(handler.saving && artifactsInBackpack.empty() && artifactsWorn.empty())
|
||||
@ -959,7 +968,7 @@ void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const s
|
||||
switch(bearerType())
|
||||
{
|
||||
case ArtBearer::HERO:
|
||||
serializeJsonHero(handler);
|
||||
serializeJsonHero(handler, map);
|
||||
break;
|
||||
case ArtBearer::CREATURE:
|
||||
serializeJsonCreature(handler);
|
||||
@ -973,11 +982,11 @@ void CArtifactSet::serializeJsonArtifacts(JsonSerializeFormat & handler, const s
|
||||
}
|
||||
}
|
||||
|
||||
void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler)
|
||||
void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler, CMap * map)
|
||||
{
|
||||
for(const auto & slot : ArtifactUtils::allWornSlots())
|
||||
{
|
||||
serializeJsonSlot(handler, slot);
|
||||
serializeJsonSlot(handler, slot, map);
|
||||
}
|
||||
|
||||
std::vector<ArtifactID> backpackTemp;
|
||||
@ -993,7 +1002,7 @@ void CArtifactSet::serializeJsonHero(JsonSerializeFormat & handler)
|
||||
{
|
||||
for(const ArtifactID & artifactID : backpackTemp)
|
||||
{
|
||||
auto * artifact = ArtifactUtils::createArtifact(artifactID);
|
||||
auto * artifact = map->createArtifact(artifactID);
|
||||
auto slot = ArtifactPosition::BACKPACK_START + artifactsInBackpack.size();
|
||||
if(artifact->getType()->canBePutAt(this, slot))
|
||||
{
|
||||
@ -1014,7 +1023,7 @@ void CArtifactSet::serializeJsonCommander(JsonSerializeFormat & handler)
|
||||
logGlobal->error("CArtifactSet::serializeJsonCommander not implemented");
|
||||
}
|
||||
|
||||
void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const ArtifactPosition & slot)
|
||||
void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const ArtifactPosition & slot, CMap * map)
|
||||
{
|
||||
ArtifactID artifactID;
|
||||
|
||||
@ -1034,7 +1043,7 @@ void CArtifactSet::serializeJsonSlot(JsonSerializeFormat & handler, const Artifa
|
||||
|
||||
if(artifactID != ArtifactID::NONE)
|
||||
{
|
||||
auto * artifact = ArtifactUtils::createArtifact(artifactID.toEnum());
|
||||
auto * artifact = map->createArtifact(artifactID.toEnum());
|
||||
|
||||
if(artifact->getType()->canBePutAt(this, slot))
|
||||
{
|
||||
|
@ -22,6 +22,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CArtHandler;
|
||||
class CGHeroInstance;
|
||||
class CMap;
|
||||
class CArtifactSet;
|
||||
class CArtifactInstance;
|
||||
class JsonSerializeFormat;
|
||||
@ -179,11 +180,12 @@ private:
|
||||
|
||||
struct DLL_LINKAGE ArtSlotInfo
|
||||
{
|
||||
CArtifactInstance * artifact;
|
||||
const CArtifactInstance * artifact;
|
||||
bool locked; //if locked, then artifact points to the combined artifact
|
||||
|
||||
ArtSlotInfo() : artifact(nullptr), locked(false) {}
|
||||
const CArtifactInstance * getArt() const;
|
||||
ArtifactInstanceID getID() const;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h)
|
||||
{
|
||||
@ -195,7 +197,7 @@ struct DLL_LINKAGE ArtSlotInfo
|
||||
class DLL_LINKAGE CArtifactSet : public virtual Serializeable
|
||||
{
|
||||
public:
|
||||
using ArtPlacementMap = std::map<CArtifactInstance*, ArtifactPosition>;
|
||||
using ArtPlacementMap = std::map<const CArtifactInstance*, ArtifactPosition>;
|
||||
|
||||
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
|
||||
std::map<ArtifactPosition, ArtSlotInfo> artifactsWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
|
||||
@ -203,7 +205,8 @@ public:
|
||||
|
||||
const ArtSlotInfo * getSlot(const ArtifactPosition & pos) const;
|
||||
void lockSlot(const ArtifactPosition & pos);
|
||||
CArtifactInstance * getArt(const ArtifactPosition & pos, bool excludeLocked = true) const;
|
||||
const CArtifactInstance * getArt(const ArtifactPosition & pos, bool excludeLocked = true) const;
|
||||
ArtifactInstanceID getArtID(const ArtifactPosition & pos, bool excludeLocked = true) const;
|
||||
/// Looks for first artifact with given ID
|
||||
ArtifactPosition getArtPos(const ArtifactID & aid, bool onlyWorn = true, bool allowLocked = true) const;
|
||||
ArtifactPosition getArtPos(const CArtifactInstance * art) const;
|
||||
@ -212,7 +215,7 @@ public:
|
||||
bool isPositionFree(const ArtifactPosition & pos, bool onlyLockCheck = false) const;
|
||||
|
||||
virtual ArtBearer::ArtBearer bearerType() const = 0;
|
||||
virtual ArtPlacementMap putArtifact(const ArtifactPosition & slot, CArtifactInstance * art);
|
||||
virtual ArtPlacementMap putArtifact(const ArtifactPosition & slot, const CArtifactInstance * art);
|
||||
virtual void removeArtifact(const ArtifactPosition & slot);
|
||||
virtual ~CArtifactSet() = default;
|
||||
|
||||
@ -224,15 +227,15 @@ public:
|
||||
|
||||
void artDeserializationFix(CBonusSystemNode *node);
|
||||
|
||||
void serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName);
|
||||
void serializeJsonArtifacts(JsonSerializeFormat & handler, const std::string & fieldName, CMap * map);
|
||||
const CArtifactInstance * getCombinedArtWithPart(const ArtifactID & partId) const;
|
||||
|
||||
private:
|
||||
void serializeJsonHero(JsonSerializeFormat & handler);
|
||||
void serializeJsonHero(JsonSerializeFormat & handler, CMap * map);
|
||||
void serializeJsonCreature(JsonSerializeFormat & handler);
|
||||
void serializeJsonCommander(JsonSerializeFormat & handler);
|
||||
|
||||
void serializeJsonSlot(JsonSerializeFormat & handler, const ArtifactPosition & slot);//normal slots
|
||||
void serializeJsonSlot(JsonSerializeFormat & handler, const ArtifactPosition & slot, CMap * map);//normal slots
|
||||
};
|
||||
|
||||
// Used to try on artifacts before the claimed changes have been applied
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
void CCombinedArtifactInstance::addPart(CArtifactInstance * art, const ArtifactPosition & slot)
|
||||
void CCombinedArtifactInstance::addPart(const CArtifactInstance * art, const ArtifactPosition & slot)
|
||||
{
|
||||
auto artInst = static_cast<CArtifactInstance*>(this);
|
||||
assert(vstd::contains_if(artInst->getType()->getConstituents(),
|
||||
@ -27,7 +27,7 @@ void CCombinedArtifactInstance::addPart(CArtifactInstance * art, const ArtifactP
|
||||
}));
|
||||
assert(art->getParentNodes().size() == 1 && art->getParentNodes().front() == art->getType());
|
||||
partsInfo.emplace_back(art, slot);
|
||||
artInst->attachTo(*art);
|
||||
artInst->attachToSource(*art);
|
||||
}
|
||||
|
||||
bool CCombinedArtifactInstance::isPart(const CArtifactInstance * supposedPart) const
|
||||
@ -173,7 +173,7 @@ void CArtifactInstance::deserializationFix()
|
||||
{
|
||||
setType(artTypeID.toArtifact());
|
||||
for(PartInfo & part : partsInfo)
|
||||
attachTo(*part.art);
|
||||
attachToSource(*part.art);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -10,7 +10,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "bonuses/CBonusSystemNode.h"
|
||||
#include "GameConstants.h"
|
||||
#include "CArtHandler.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
@ -24,17 +23,17 @@ protected:
|
||||
public:
|
||||
struct PartInfo
|
||||
{
|
||||
CArtifactInstance * art;
|
||||
const CArtifactInstance * art;
|
||||
ArtifactPosition slot;
|
||||
template <typename Handler> void serialize(Handler & h)
|
||||
{
|
||||
h & art;
|
||||
h & slot;
|
||||
}
|
||||
PartInfo(CArtifactInstance * art = nullptr, const ArtifactPosition & slot = ArtifactPosition::PRE_FIRST)
|
||||
PartInfo(const CArtifactInstance * art = nullptr, const ArtifactPosition & slot = ArtifactPosition::PRE_FIRST)
|
||||
: art(art), slot(slot) {};
|
||||
};
|
||||
void addPart(CArtifactInstance * art, const ArtifactPosition & slot);
|
||||
void addPart(const CArtifactInstance * art, const ArtifactPosition & slot);
|
||||
// Checks if supposed part inst is part of this combined art inst
|
||||
bool isPart(const CArtifactInstance * supposedPart) const;
|
||||
bool hasParts() const;
|
||||
@ -65,7 +64,7 @@ public:
|
||||
void growingUp();
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CArtifactInstance
|
||||
class DLL_LINKAGE CArtifactInstance final
|
||||
: public CBonusSystemNode, public CCombinedArtifactInstance, public CScrollArtifactInstance, public CGrowingArtifactInstance
|
||||
{
|
||||
protected:
|
||||
|
@ -901,12 +901,12 @@ ArtBearer::ArtBearer CStackInstance::bearerType() const
|
||||
return ArtBearer::CREATURE;
|
||||
}
|
||||
|
||||
CStackInstance::ArtPlacementMap CStackInstance::putArtifact(const ArtifactPosition & pos, CArtifactInstance * art)
|
||||
CStackInstance::ArtPlacementMap CStackInstance::putArtifact(const ArtifactPosition & pos, const CArtifactInstance * art)
|
||||
{
|
||||
assert(!getArt(pos));
|
||||
assert(art->canBePutAt(this, pos));
|
||||
|
||||
attachTo(*art);
|
||||
attachToSource(*art);
|
||||
return CArtifactSet::putArtifact(pos, art);
|
||||
}
|
||||
|
||||
@ -914,7 +914,7 @@ void CStackInstance::removeArtifact(const ArtifactPosition & pos)
|
||||
{
|
||||
assert(getArt(pos));
|
||||
|
||||
detachFrom(*getArt(pos));
|
||||
detachFromSource(*getArt(pos));
|
||||
CArtifactSet::removeArtifact(pos);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||
virtual void giveStackExp(TExpType exp);
|
||||
bool valid(bool allowUnrandomized) const;
|
||||
ArtPlacementMap putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) override;//from CArtifactSet
|
||||
ArtPlacementMap putArtifact(const ArtifactPosition & pos, const CArtifactInstance * art) override;//from CArtifactSet
|
||||
void removeArtifact(const ArtifactPosition & pos) override;
|
||||
ArtBearer::ArtBearer bearerType() const override; //from CArtifactSet
|
||||
std::string nodeName() const override; //from CBonusSystemnode
|
||||
|
@ -951,7 +951,7 @@ void CGameInfoCallback::calculatePaths(const std::shared_ptr<PathfinderConfig> &
|
||||
|
||||
const CArtifactInstance * CGameInfoCallback::getArtInstance( ArtifactInstanceID aid ) const
|
||||
{
|
||||
return gs->getMap().artInstances.at(aid.num);
|
||||
return gs->getMap().getArtifactInstance(aid);
|
||||
}
|
||||
|
||||
const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid ) const
|
||||
|
@ -251,7 +251,7 @@ PlayerState * CNonConstInfoCallback::getPlayerState(const PlayerColor & color, b
|
||||
|
||||
CArtifactInstance * CNonConstInfoCallback::getArtInstance(const ArtifactInstanceID & aid)
|
||||
{
|
||||
return gs->getMap().artInstances.at(aid.num);
|
||||
return gs->getMap().getArtifactInstance(aid);
|
||||
}
|
||||
|
||||
CGObjectInstance * CNonConstInfoCallback::getObjInstance(const ObjectInstanceID & oid)
|
||||
|
@ -483,8 +483,7 @@ CGHeroInstance * CampaignState::crossoverDeserialize(const JsonNode & node, CMap
|
||||
hero->serializeJsonOptions(handler);
|
||||
if (map)
|
||||
{
|
||||
hero->serializeJsonArtifacts(handler, "artifacts");
|
||||
map->addNewArtifactInstance(*hero);
|
||||
hero->serializeJsonArtifacts(handler, "artifacts", map);
|
||||
}
|
||||
return hero;
|
||||
}
|
||||
|
@ -1618,12 +1618,11 @@ void CGameState::attachArmedObjects()
|
||||
|
||||
bool CGameState::giveHeroArtifact(CGHeroInstance * h, const ArtifactID & aid)
|
||||
{
|
||||
CArtifactInstance * ai = ArtifactUtils::createArtifact(aid);
|
||||
map->addNewArtifactInstance(ai);
|
||||
CArtifactInstance * ai = createArtifact(aid);
|
||||
auto slot = ArtifactUtils::getArtAnyPosition(h, aid);
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
{
|
||||
map->putArtifactInstance(*h, ai, slot);
|
||||
map->putArtifactInstance(*h, ai->getId(), slot);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@ -1766,4 +1765,14 @@ ArtifactID CGameState::pickRandomArtifact(vstd::RNG & rand, int flags)
|
||||
return pickRandomArtifact(rand, flags, [](const ArtifactID &) { return true; });
|
||||
}
|
||||
|
||||
CArtifactInstance * CGameState::createScroll(const SpellID & spellId)
|
||||
{
|
||||
return map->createScroll(spellId);
|
||||
}
|
||||
|
||||
CArtifactInstance * CGameState::createArtifact(const ArtifactID & artID, const SpellID & spellId)
|
||||
{
|
||||
return map->createArtifact(artID, spellId);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -107,6 +107,9 @@ public:
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags, std::function<bool(ArtifactID)> accepts);
|
||||
ArtifactID pickRandomArtifact(vstd::RNG & rand, std::set<ArtifactID> filtered);
|
||||
|
||||
CArtifactInstance * createScroll(const SpellID & spellId);
|
||||
CArtifactInstance * createArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
|
||||
|
||||
/// Returns battle in which selected player is engaged, or nullptr if none.
|
||||
/// Can NOT be used with neutral player, use battle by ID instead
|
||||
const BattleInfo * getBattle(const PlayerColor & player) const;
|
||||
|
@ -325,10 +325,10 @@ void CGameStateCampaign::giveCampaignBonusToHero(CGHeroInstance * hero)
|
||||
}
|
||||
case CampaignBonusType::SPELL_SCROLL:
|
||||
{
|
||||
CArtifactInstance * scroll = ArtifactUtils::createScroll(SpellID(curBonus->info2));
|
||||
const auto scroll = gameState->createScroll(SpellID(curBonus->info2));
|
||||
const auto slot = ArtifactUtils::getArtAnyPosition(hero, scroll->getTypeId());
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
gameState->map->putArtifactInstance(*hero, scroll, slot);
|
||||
gameState->map->putArtifactInstance(*hero, scroll->getId(), slot);
|
||||
else
|
||||
logGlobal->error("Cannot give starting scroll - no free slots!");
|
||||
break;
|
||||
@ -432,7 +432,7 @@ void CGameStateCampaign::transferMissingArtifacts(const CampaignTravel & travelO
|
||||
|
||||
const auto slot = ArtifactUtils::getArtAnyPosition(receiver, artifact->getTypeId());
|
||||
if(ArtifactUtils::isSlotEquipment(slot) || ArtifactUtils::isSlotBackpack(slot))
|
||||
gameState->map->putArtifactInstance(*receiver, artifact, slot);
|
||||
gameState->map->putArtifactInstance(*receiver, artifact->getId(), slot);
|
||||
else
|
||||
logGlobal->error("Cannot transfer artifact - no free slots!");
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
// hero starts with default spellbook presence status
|
||||
if(!getArt(ArtifactPosition::SPELLBOOK) && getHeroType()->haveSpellBook)
|
||||
{
|
||||
auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
|
||||
auto artifact = cb->gameState()->createArtifact(ArtifactID::SPELLBOOK);
|
||||
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
|
||||
}
|
||||
}
|
||||
@ -414,7 +414,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
|
||||
|
||||
if(!getArt(ArtifactPosition::MACH4))
|
||||
{
|
||||
auto artifact = ArtifactUtils::createArtifact(ArtifactID::CATAPULT);
|
||||
auto artifact = cb->gameState()->createArtifact(ArtifactID::CATAPULT);
|
||||
putArtifact(ArtifactPosition::MACH4, artifact); //everyone has a catapult
|
||||
}
|
||||
|
||||
@ -527,7 +527,7 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
|
||||
|
||||
if(!getArt(slot))
|
||||
{
|
||||
auto artifact = ArtifactUtils::createArtifact(aid);
|
||||
auto artifact = cb->gameState()->createArtifact(aid);
|
||||
putArtifact(slot, artifact);
|
||||
}
|
||||
else
|
||||
@ -1236,12 +1236,12 @@ std::string CGHeroInstance::getBiographyTextID() const
|
||||
return ""; //for random hero
|
||||
}
|
||||
|
||||
CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(const ArtifactPosition & pos, CArtifactInstance * art)
|
||||
CGHeroInstance::ArtPlacementMap CGHeroInstance::putArtifact(const ArtifactPosition & pos, const CArtifactInstance * art)
|
||||
{
|
||||
assert(art->canBePutAt(this, pos));
|
||||
|
||||
if(ArtifactUtils::isSlotEquipment(pos))
|
||||
attachTo(*art);
|
||||
attachToSource(*art);
|
||||
return CArtifactSet::putArtifact(pos, art);
|
||||
}
|
||||
|
||||
@ -1252,7 +1252,7 @@ void CGHeroInstance::removeArtifact(const ArtifactPosition & pos)
|
||||
|
||||
CArtifactSet::removeArtifact(pos);
|
||||
if(ArtifactUtils::isSlotEquipment(pos))
|
||||
detachFrom(*art);
|
||||
detachFromSource(*art);
|
||||
}
|
||||
|
||||
bool CGHeroInstance::hasSpellbook() const
|
||||
@ -1768,7 +1768,7 @@ void CGHeroInstance::serializeCommonOptions(JsonSerializeFormat & handler)
|
||||
handler.serializeIdArray("spellBook", spells);
|
||||
|
||||
if(handler.saving)
|
||||
CArtifactSet::serializeJsonArtifacts(handler, "artifacts");
|
||||
CArtifactSet::serializeJsonArtifacts(handler, "artifacts", &cb->gameState()->getMap());
|
||||
}
|
||||
|
||||
void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
|
||||
|
@ -260,7 +260,7 @@ public:
|
||||
void initHero(vstd::RNG & rand);
|
||||
void initHero(vstd::RNG & rand, const HeroTypeID & SUBID);
|
||||
|
||||
ArtPlacementMap putArtifact(const ArtifactPosition & pos, CArtifactInstance * art) override;
|
||||
ArtPlacementMap putArtifact(const ArtifactPosition & pos, const CArtifactInstance * art) override;
|
||||
void removeArtifact(const ArtifactPosition & pos) override;
|
||||
void initExp(vstd::RNG & rand);
|
||||
void initArmy(vstd::RNG & rand, IArmyDescriptor *dst = nullptr);
|
||||
|
@ -663,10 +663,8 @@ void CGArtifact::initObj(vstd::RNG & rand)
|
||||
if(ID == Obj::ARTIFACT)
|
||||
{
|
||||
if (!storedArtifact)
|
||||
{
|
||||
storedArtifact = ArtifactUtils::createArtifact(ArtifactID());
|
||||
cb->gameState()->getMap().addNewArtifactInstance(storedArtifact);
|
||||
}
|
||||
storedArtifact = cb->gameState()->createArtifact(ArtifactID());
|
||||
|
||||
if(!storedArtifact->getType())
|
||||
storedArtifact->setType(getArtifact().toArtifact());
|
||||
}
|
||||
@ -813,15 +811,6 @@ void CGArtifact::blockingDialogAnswered(const CGHeroInstance *hero, int32_t answ
|
||||
cb->startBattle(hero, this);
|
||||
}
|
||||
|
||||
void CGArtifact::afterAddToMap(CMap * map)
|
||||
{
|
||||
//Artifacts from map objects are never removed
|
||||
//FIXME: This should be revertible in map editor
|
||||
|
||||
if(ID == Obj::SPELL_SCROLL && storedArtifact && storedArtifact->getId().getNum() < 0)
|
||||
map->addNewArtifactInstance(storedArtifact);
|
||||
}
|
||||
|
||||
void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
|
||||
{
|
||||
handler.serializeStruct("guardMessage", message);
|
||||
|
@ -109,7 +109,6 @@ public:
|
||||
void initObj(vstd::RNG & rand) override;
|
||||
void pickRandomObject(vstd::RNG & rand) override;
|
||||
|
||||
void afterAddToMap(CMap * map) override;
|
||||
BattleField getBattlefield() const override;
|
||||
|
||||
ArtifactID getArtifact() const;
|
||||
|
@ -194,9 +194,6 @@ CMap::~CMap()
|
||||
for(auto obj : objects)
|
||||
obj.dellNull();
|
||||
|
||||
for(auto artInstance : artInstances)
|
||||
artInstance.dellNull();
|
||||
|
||||
resetStaticData();
|
||||
}
|
||||
|
||||
@ -467,33 +464,10 @@ void CMap::checkForObjectives()
|
||||
}
|
||||
}
|
||||
|
||||
void CMap::addNewArtifactInstance(CArtifactSet & artSet)
|
||||
{
|
||||
for(const auto & [slot, slotInfo] : artSet.artifactsWorn)
|
||||
{
|
||||
if(!slotInfo.locked && slotInfo.getArt())
|
||||
addNewArtifactInstance(slotInfo.artifact);
|
||||
}
|
||||
for(const auto & slotInfo : artSet.artifactsInBackpack)
|
||||
addNewArtifactInstance(slotInfo.artifact);
|
||||
}
|
||||
|
||||
void CMap::addNewArtifactInstance(ConstTransitivePtr<CArtifactInstance> art)
|
||||
{
|
||||
assert(art);
|
||||
assert(art->getId() == -1);
|
||||
art->setId(static_cast<ArtifactInstanceID>(artInstances.size()));
|
||||
artInstances.emplace_back(art);
|
||||
|
||||
for(const auto & partInfo : art->getPartsInfo())
|
||||
addNewArtifactInstance(partInfo.art);
|
||||
}
|
||||
|
||||
void CMap::eraseArtifactInstance(CArtifactInstance * art)
|
||||
void CMap::eraseArtifactInstance(ArtifactInstanceID art)
|
||||
{
|
||||
//TODO: handle for artifacts removed in map editor
|
||||
assert(artInstances[art->getId().getNum()] == art);
|
||||
artInstances[art->getId().getNum()].dellNull();
|
||||
artInstances[art.getNum()] = nullptr;
|
||||
}
|
||||
|
||||
void CMap::moveArtifactInstance(
|
||||
@ -502,26 +476,29 @@ void CMap::moveArtifactInstance(
|
||||
{
|
||||
auto art = srcSet.getArt(srcSlot);
|
||||
removeArtifactInstance(srcSet, srcSlot);
|
||||
putArtifactInstance(dstSet, art, dstSlot);
|
||||
putArtifactInstance(dstSet, art->getId(), dstSlot);
|
||||
}
|
||||
|
||||
void CMap::putArtifactInstance(CArtifactSet & set, CArtifactInstance * art, const ArtifactPosition & slot)
|
||||
void CMap::putArtifactInstance(CArtifactSet & set, ArtifactInstanceID artID, const ArtifactPosition & slot)
|
||||
{
|
||||
art->addPlacementMap(set.putArtifact(slot, art));
|
||||
auto artifact = artInstances.at(artID.getNum());
|
||||
|
||||
artifact->addPlacementMap(set.putArtifact(slot, artifact.get()));
|
||||
}
|
||||
|
||||
void CMap::removeArtifactInstance(CArtifactSet & set, const ArtifactPosition & slot)
|
||||
{
|
||||
auto art = set.getArt(slot);
|
||||
assert(art);
|
||||
ArtifactInstanceID artID = set.getArtID(slot);
|
||||
auto artifact = artInstances.at(artID.getNum());
|
||||
assert(artifact);
|
||||
set.removeArtifact(slot);
|
||||
CArtifactSet::ArtPlacementMap partsMap;
|
||||
for(auto & part : art->getPartsInfo())
|
||||
for(auto & part : artifact->getPartsInfo())
|
||||
{
|
||||
if(part.slot != ArtifactPosition::PRE_FIRST)
|
||||
partsMap.try_emplace(part.art, ArtifactPosition::PRE_FIRST);
|
||||
}
|
||||
art->addPlacementMap(partsMap);
|
||||
artifact->addPlacementMap(partsMap);
|
||||
}
|
||||
|
||||
void CMap::addNewQuestInstance(std::shared_ptr<CQuest> quest)
|
||||
@ -777,4 +754,52 @@ void CMap::overrideGameSettings(const JsonNode & input)
|
||||
return gameSettings->loadOverrides(input);
|
||||
}
|
||||
|
||||
CArtifactInstance * CMap::createScroll(const SpellID & spellId)
|
||||
{
|
||||
return createArtifact(ArtifactID::SPELL_SCROLL, spellId);
|
||||
}
|
||||
|
||||
CArtifactInstance * CMap::createSingleArtifact(const ArtifactID & artId, const SpellID & spellId)
|
||||
{
|
||||
return new CArtifactInstance();
|
||||
}
|
||||
|
||||
CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID & spellId)
|
||||
{
|
||||
if(!artID.hasValue())
|
||||
return new CArtifactInstance(); // random, empty //TODO: make this illegal & remove?
|
||||
|
||||
auto art = artID.toArtifact();
|
||||
|
||||
auto artInst = new CArtifactInstance(art);
|
||||
if(art->isCombined() && !art->isFused())
|
||||
{
|
||||
for(const auto & part : art->getConstituents())
|
||||
artInst->addPart(createArtifact(part->getId(), spellId), ArtifactPosition::PRE_FIRST);
|
||||
}
|
||||
if(art->isGrowing())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
CArtifactInstance * CMap::getArtifactInstance(const ArtifactInstanceID & artifactID)
|
||||
{
|
||||
return artInstances.at(artifactID.getNum()).get();
|
||||
}
|
||||
|
||||
const CArtifactInstance * CMap::getArtifactInstance(const ArtifactInstanceID & artifactID) const
|
||||
{
|
||||
return artInstances.at(artifactID.getNum()).get();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -64,6 +64,8 @@ class DLL_LINKAGE CMap : public CMapHeader, public GameCallbackHolder
|
||||
std::unique_ptr<GameSettings> gameSettings;
|
||||
|
||||
std::vector< std::shared_ptr<CQuest> > quests;
|
||||
std::vector< std::shared_ptr<CArtifactInstance> > artInstances;
|
||||
|
||||
public:
|
||||
explicit CMap(IGameCallback *cb);
|
||||
~CMap();
|
||||
@ -83,11 +85,16 @@ public:
|
||||
void removeBlockVisTiles(CGObjectInstance * obj, bool total = false);
|
||||
void calculateGuardingGreaturePositions();
|
||||
|
||||
void addNewArtifactInstance(CArtifactSet & artSet);
|
||||
void addNewArtifactInstance(ConstTransitivePtr<CArtifactInstance> art);
|
||||
void eraseArtifactInstance(CArtifactInstance * art);
|
||||
CArtifactInstance * createScroll(const SpellID & spellId);
|
||||
CArtifactInstance * createArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
|
||||
CArtifactInstance * createSingleArtifact(const ArtifactID & artId, const SpellID & spellId = SpellID::NONE);
|
||||
|
||||
CArtifactInstance * getArtifactInstance(const ArtifactInstanceID & artifactID);
|
||||
const CArtifactInstance * getArtifactInstance(const ArtifactInstanceID & artifactID) const;
|
||||
|
||||
void eraseArtifactInstance(const ArtifactInstanceID art);
|
||||
void moveArtifactInstance(CArtifactSet & srcSet, const ArtifactPosition & srcSlot, CArtifactSet & dstSet, const ArtifactPosition & dstSlot);
|
||||
void putArtifactInstance(CArtifactSet & set, CArtifactInstance * art, const ArtifactPosition & slot);
|
||||
void putArtifactInstance(CArtifactSet & set, const ArtifactInstanceID art, const ArtifactPosition & slot);
|
||||
void removeArtifactInstance(CArtifactSet & set, const ArtifactPosition & slot);
|
||||
|
||||
void addNewQuestInstance(std::shared_ptr<CQuest> quest);
|
||||
@ -134,7 +141,6 @@ public:
|
||||
//Central lists of items in game. Position of item in the vectors below is their (instance) id.
|
||||
std::vector< ConstTransitivePtr<CGObjectInstance> > objects;
|
||||
std::vector< ConstTransitivePtr<CGTownInstance> > towns;
|
||||
std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances;
|
||||
std::vector< ConstTransitivePtr<CGHeroInstance> > allHeroes; //indexed by [hero_type_id]; on map, disposed, prisons, etc.
|
||||
|
||||
//Helper lists
|
||||
|
@ -1006,9 +1006,8 @@ bool CMapLoaderH3M::loadArtifactToSlot(CGHeroInstance * hero, int slot)
|
||||
// Artifact seems to be missing in game, so skip artifacts that don't fit target slot
|
||||
if(ArtifactID(artifactID).toArtifact()->canBePutAt(hero, ArtifactPosition(slot)))
|
||||
{
|
||||
auto * artifact = ArtifactUtils::createArtifact(artifactID, scrollSpell);
|
||||
map->putArtifactInstance(*hero, artifact, slot);
|
||||
map->addNewArtifactInstance(artifact);
|
||||
auto * artifact = map->createArtifact(artifactID, scrollSpell);
|
||||
map->putArtifactInstance(*hero, artifact->getId(), slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1407,8 +1406,7 @@ CGObjectInstance * CMapLoaderH3M::readArtifact(const int3 & mapPosition, std::sh
|
||||
logGlobal->warn("Map '%s': Artifact %s: not implemented pickup mode %d (flags: %d)", mapName, mapPosition.toString(), pickupMode, static_cast<int>(pickupFlags));
|
||||
}
|
||||
|
||||
object->storedArtifact = ArtifactUtils::createArtifact(artID, SpellID::NONE);
|
||||
map->addNewArtifactInstance(object->storedArtifact);
|
||||
object->storedArtifact = map->createArtifact(artID, SpellID::NONE);
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -1418,8 +1416,7 @@ CGObjectInstance * CMapLoaderH3M::readScroll(const int3 & mapPosition, std::shar
|
||||
readMessageAndGuards(object->message, object, mapPosition);
|
||||
SpellID spellID = reader->readSpell32();
|
||||
|
||||
object->storedArtifact = ArtifactUtils::createArtifact(ArtifactID::SPELL_SCROLL, spellID.getNum());
|
||||
map->addNewArtifactInstance(object->storedArtifact);
|
||||
object->storedArtifact = map->createArtifact(ArtifactID::SPELL_SCROLL, spellID.getNum());
|
||||
return object;
|
||||
}
|
||||
|
||||
|
@ -1105,15 +1105,13 @@ void CMapLoaderJson::MapObjectLoader::configure()
|
||||
artID = art->getArtifact();
|
||||
}
|
||||
|
||||
art->storedArtifact = ArtifactUtils::createArtifact(artID, spellID.getNum());
|
||||
owner->map->addNewArtifactInstance(art->storedArtifact);
|
||||
art->storedArtifact = owner->map->createArtifact(artID, spellID.getNum());
|
||||
}
|
||||
|
||||
if(auto * hero = dynamic_cast<CGHeroInstance *>(instance))
|
||||
{
|
||||
auto o = handler.enterStruct("options");
|
||||
hero->serializeJsonArtifacts(handler, "artifacts");
|
||||
owner->map->addNewArtifactInstance(*hero);
|
||||
hero->serializeJsonArtifacts(handler, "artifacts", owner->map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1513,8 +1513,7 @@ void NewObject::applyGs(CGameState *gs)
|
||||
|
||||
void NewArtifact::applyGs(CGameState *gs)
|
||||
{
|
||||
auto art = ArtifactUtils::createArtifact(artId, spellId);
|
||||
gs->getMap().addNewArtifactInstance(art);
|
||||
auto art = gs->createArtifact(artId, spellId);
|
||||
PutArtifact pa(art->getId(), ArtifactLocation(artHolder, pos), false);
|
||||
pa.applyGs(gs);
|
||||
}
|
||||
@ -1732,7 +1731,7 @@ void PutArtifact::applyGs(CGameState *gs)
|
||||
assert(hero);
|
||||
assert(art && art->canBePutAt(hero, al.slot));
|
||||
assert(ArtifactUtils::checkIfSlotValid(*hero, al.slot));
|
||||
gs->getMap().putArtifactInstance(*hero, art, al.slot);
|
||||
gs->getMap().putArtifactInstance(*hero, art->getId(), al.slot);
|
||||
}
|
||||
|
||||
void BulkEraseArtifacts::applyGs(CGameState *gs)
|
||||
@ -1797,7 +1796,7 @@ void BulkMoveArtifacts::applyGs(CGameState *gs)
|
||||
{
|
||||
auto * art = initArtSet.getArt(slotsPair.srcPos);
|
||||
assert(art);
|
||||
gs->getMap().putArtifactInstance(dstArtSet, art, slotsPair.dstPos);
|
||||
gs->getMap().putArtifactInstance(dstArtSet, art->getId(), slotsPair.dstPos);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1828,8 +1827,7 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
||||
return art->getId() == builtArt->getId();
|
||||
}));
|
||||
|
||||
auto * combinedArt = new CArtifactInstance(builtArt);
|
||||
gs->getMap().addNewArtifactInstance(combinedArt);
|
||||
auto * combinedArt = gs->getMap().createSingleArtifact(artId);
|
||||
|
||||
// Find slots for all involved artifacts
|
||||
std::set<ArtifactPosition, std::greater<>> slotsInvolved = { al.slot };
|
||||
@ -1882,14 +1880,15 @@ void AssembledArtifact::applyGs(CGameState *gs)
|
||||
}
|
||||
|
||||
// Put new combined artifacts
|
||||
gs->getMap().putArtifactInstance(*artSet, combinedArt, al.slot);
|
||||
gs->getMap().putArtifactInstance(*artSet, combinedArt->getId(), al.slot);
|
||||
}
|
||||
|
||||
void DisassembledArtifact::applyGs(CGameState *gs)
|
||||
{
|
||||
auto hero = gs->getHero(al.artHolder);
|
||||
assert(hero);
|
||||
auto disassembledArt = hero->getArt(al.slot);
|
||||
auto disassembledArtID = hero->getArtID(al.slot);
|
||||
auto disassembledArt = gs->getArtInstance(disassembledArtID);
|
||||
assert(disassembledArt);
|
||||
|
||||
const auto parts = disassembledArt->getPartsInfo();
|
||||
@ -1898,10 +1897,10 @@ void DisassembledArtifact::applyGs(CGameState *gs)
|
||||
{
|
||||
// ArtifactPosition::PRE_FIRST is value of main part slot -> it'll replace combined artifact in its pos
|
||||
auto slot = (ArtifactUtils::isSlotEquipment(part.slot) ? part.slot : al.slot);
|
||||
disassembledArt->detachFrom(*part.art);
|
||||
gs->getMap().putArtifactInstance(*hero, part.art, slot);
|
||||
disassembledArt->detachFromSource(*part.art);
|
||||
gs->getMap().putArtifactInstance(*hero, part.art->getId(), slot);
|
||||
}
|
||||
gs->getMap().eraseArtifactInstance(disassembledArt);
|
||||
gs->getMap().eraseArtifactInstance(disassembledArt->getId());
|
||||
}
|
||||
|
||||
void HeroVisit::applyGs(CGameState *gs)
|
||||
@ -2130,12 +2129,10 @@ void BattleResultAccepted::applyGs(CGameState *gs)
|
||||
if(winnerHero->getCommander() && winnerHero->getCommander()->alive)
|
||||
{
|
||||
for(auto & art : winnerHero->getCommander()->artifactsWorn)
|
||||
art.second.artifact->growingUp();
|
||||
gs->getArtInstance(art.second.getID())->growingUp();
|
||||
}
|
||||
for(auto & art : winnerHero->artifactsWorn)
|
||||
{
|
||||
art.second.artifact->growingUp();
|
||||
}
|
||||
gs->getArtInstance(art.second.getID())->growingUp();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2503,4 +2500,11 @@ const CArtifactInstance * ArtSlotInfo::getArt() const
|
||||
return artifact;
|
||||
}
|
||||
|
||||
ArtifactInstanceID ArtSlotInfo::getID() const
|
||||
{
|
||||
if(locked || artifact == nullptr)
|
||||
return {};
|
||||
return artifact->getId();
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -278,7 +278,7 @@ void TreasurePlacer::addScrolls()
|
||||
if(map.isAllowedSpell(spellID) && spellID.toSpell()->getLevel() == i + 1)
|
||||
out.push_back(spellID);
|
||||
}
|
||||
auto * a = ArtifactUtils::createScroll(*RandomGeneratorUtil::nextItem(out, zone.getRand()));
|
||||
auto * a = map.mapInstance->createScroll(*RandomGeneratorUtil::nextItem(out, zone.getRand()));
|
||||
obj->storedArtifact = a;
|
||||
return obj;
|
||||
};
|
||||
|
@ -330,7 +330,7 @@ public:
|
||||
{
|
||||
// This pointers is already loaded. The "data" needs to be pointed to it,
|
||||
// so their shared state is actually shared.
|
||||
data = std::static_pointer_cast<T>(itr->second);
|
||||
data = std::dynamic_pointer_cast<T>(itr->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -27,8 +27,8 @@ void CSerializer::addStdVecItems(CGameState *gs, GameLibrary *lib)
|
||||
[](const CGObjectInstance &obj){ return obj.id; });
|
||||
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->getMap().allHeroes,
|
||||
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
|
||||
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->getMap().artInstances,
|
||||
[](const CArtifactInstance &artInst){ return artInst.getId(); });
|
||||
// registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->getMap().artInstances,
|
||||
// [](const CArtifactInstance &artInst){ return artInst.getId(); });
|
||||
// TODO
|
||||
// registerVectoredType<CQuest, si32>(&gs->getMap().quests,
|
||||
// [](const CQuest &q){ return q.qid; });
|
||||
|
@ -13,12 +13,16 @@
|
||||
#include "ui_heroartifactswidget.h"
|
||||
#include "inspector.h"
|
||||
#include "mapeditorroles.h"
|
||||
#include "../mapcontroller.h"
|
||||
|
||||
#include "../../lib/ArtifactUtils.h"
|
||||
#include "../../lib/constants/StringConstants.h"
|
||||
#include "../../lib/mapping/CMap.h"
|
||||
|
||||
HeroArtifactsWidget::HeroArtifactsWidget(CGHeroInstance & h, QWidget * parent) :
|
||||
HeroArtifactsWidget::HeroArtifactsWidget(MapController & controller, CGHeroInstance & h, QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::HeroArtifactsWidget),
|
||||
controller(controller),
|
||||
hero(h),
|
||||
fittingSet(CArtifactFittingSet(h))
|
||||
{
|
||||
@ -52,7 +56,7 @@ void HeroArtifactsWidget::on_removeButton_clicked()
|
||||
|
||||
void HeroArtifactsWidget::onSaveArtifact(int32_t artifactIndex, ArtifactPosition slot)
|
||||
{
|
||||
auto artifact = ArtifactUtils::createArtifact(LIBRARY->arth->getByIndex(artifactIndex)->getId());
|
||||
auto artifact = controller.map()->createArtifact(LIBRARY->arth->getByIndex(artifactIndex)->getId());
|
||||
fittingSet.putArtifact(slot, artifact);
|
||||
addArtifactToTable(artifactIndex, slot);
|
||||
}
|
||||
@ -110,13 +114,16 @@ void HeroArtifactsWidget::commitChanges()
|
||||
}
|
||||
}
|
||||
|
||||
HeroArtifactsDelegate::HeroArtifactsDelegate(CGHeroInstance & h) : BaseInspectorItemDelegate(), hero(h)
|
||||
HeroArtifactsDelegate::HeroArtifactsDelegate(MapController & controller, CGHeroInstance & h)
|
||||
: BaseInspectorItemDelegate()
|
||||
, controller(controller)
|
||||
, hero(h)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget * HeroArtifactsDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||
{
|
||||
return new HeroArtifactsWidget(hero, parent);
|
||||
return new HeroArtifactsWidget(controller, hero, parent);
|
||||
}
|
||||
|
||||
void HeroArtifactsDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
|
||||
|
@ -17,12 +17,14 @@ namespace Ui {
|
||||
class HeroArtifactsWidget;
|
||||
}
|
||||
|
||||
class MapController;
|
||||
|
||||
class HeroArtifactsWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HeroArtifactsWidget(CGHeroInstance &, QWidget *parent = nullptr);
|
||||
explicit HeroArtifactsWidget(MapController & controller, CGHeroInstance &, QWidget *parent = nullptr);
|
||||
~HeroArtifactsWidget();
|
||||
|
||||
void obtainData();
|
||||
@ -42,6 +44,7 @@ private:
|
||||
};
|
||||
Ui::HeroArtifactsWidget * ui;
|
||||
|
||||
MapController & controller;
|
||||
CGHeroInstance & hero;
|
||||
CArtifactFittingSet fittingSet;
|
||||
|
||||
@ -55,7 +58,7 @@ class HeroArtifactsDelegate : public BaseInspectorItemDelegate
|
||||
public:
|
||||
using BaseInspectorItemDelegate::BaseInspectorItemDelegate;
|
||||
|
||||
HeroArtifactsDelegate(CGHeroInstance &);
|
||||
HeroArtifactsDelegate(MapController & controller, CGHeroInstance &);
|
||||
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const override;
|
||||
void setEditorData(QWidget * editor, const QModelIndex & index) const override;
|
||||
@ -63,5 +66,6 @@ public:
|
||||
void updateModelData(QAbstractItemModel * model, const QModelIndex & index) const override;
|
||||
|
||||
private:
|
||||
MapController & controller;
|
||||
CGHeroInstance & hero;
|
||||
};
|
||||
|
@ -38,7 +38,9 @@
|
||||
#include "../mapcontroller.h"
|
||||
|
||||
//===============IMPLEMENT OBJECT INITIALIZATION FUNCTIONS================
|
||||
Initializer::Initializer(CGObjectInstance * o, const PlayerColor & pl) : defaultPlayer(pl)
|
||||
Initializer::Initializer(MapController & controller, CGObjectInstance * o, const PlayerColor & pl)
|
||||
: defaultPlayer(pl)
|
||||
, controller(controller)
|
||||
{
|
||||
logGlobal->info("New object instance initialized");
|
||||
///IMPORTANT! initialize order should be from base objects to derived objects
|
||||
@ -203,7 +205,7 @@ void Initializer::initialize(CGArtifact * o)
|
||||
out.push_back(spell->id);
|
||||
}
|
||||
}
|
||||
auto a = ArtifactUtils::createScroll(*RandomGeneratorUtil::nextItem(out, CRandomGenerator::getDefault()));
|
||||
auto a = controller.map()->createScroll(*RandomGeneratorUtil::nextItem(out, CRandomGenerator::getDefault()));
|
||||
o->storedArtifact = a;
|
||||
}
|
||||
}
|
||||
@ -320,7 +322,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
|
||||
auto * delegate = new HeroSkillsDelegate(*o);
|
||||
addProperty(QObject::tr("Skills"), PropertyEditorPlaceholder(), delegate, false);
|
||||
addProperty(QObject::tr("Spells"), PropertyEditorPlaceholder(), new HeroSpellDelegate(*o), false);
|
||||
addProperty(QObject::tr("Artifacts"), PropertyEditorPlaceholder(), new HeroArtifactsDelegate(*o), false);
|
||||
addProperty(QObject::tr("Artifacts"), PropertyEditorPlaceholder(), new HeroArtifactsDelegate(controller, *o), false);
|
||||
|
||||
if(o->getHeroTypeID().hasValue() || o->ID == Obj::PRISON)
|
||||
{ //Hero type
|
||||
@ -640,7 +642,7 @@ void Inspector::setProperty(CGArtifact * o, const QString & key, const QVariant
|
||||
|
||||
if(o->storedArtifact && key == QObject::tr("Spell"))
|
||||
{
|
||||
o->storedArtifact = ArtifactUtils::createScroll(SpellID(value.toInt()));
|
||||
o->storedArtifact = controller.map()->createScroll(SpellID(value.toInt()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,10 @@ public:
|
||||
//DECLARE_OBJ_TYPE(CGPandoraBox);
|
||||
//DECLARE_OBJ_TYPE(CGSeerHut);
|
||||
|
||||
Initializer(CGObjectInstance *, const PlayerColor &);
|
||||
Initializer(MapController & controller, CGObjectInstance *, const PlayerColor &);
|
||||
|
||||
private:
|
||||
MapController & controller;
|
||||
PlayerColor defaultPlayer;
|
||||
};
|
||||
|
||||
|
@ -144,7 +144,7 @@ void MapController::repairMap(CMap * map)
|
||||
{
|
||||
nih->removeSpellFromSpellbook(SpellID::SPELLBOOK_PRESET);
|
||||
if(!nih->getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
|
||||
nih->putArtifact(ArtifactPosition::SPELLBOOK, ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK));
|
||||
nih->putArtifact(ArtifactPosition::SPELLBOOK, map->createArtifact(ArtifactID::SPELLBOOK));
|
||||
}
|
||||
|
||||
}
|
||||
@ -177,7 +177,7 @@ void MapController::repairMap(CMap * map)
|
||||
out.push_back(spell->id);
|
||||
}
|
||||
}
|
||||
auto a = ArtifactUtils::createScroll(*RandomGeneratorUtil::nextItem(out, CRandomGenerator::getDefault()));
|
||||
auto a = map->createScroll(*RandomGeneratorUtil::nextItem(out, CRandomGenerator::getDefault()));
|
||||
art->storedArtifact = a;
|
||||
}
|
||||
}
|
||||
@ -376,7 +376,7 @@ void MapController::pasteFromClipboard(int level)
|
||||
obj->pos = newPos;
|
||||
obj->pos.z = level;
|
||||
|
||||
Initializer init(obj, defaultPlayer);
|
||||
Initializer init(*this, obj, defaultPlayer);
|
||||
_map->getEditManager()->insertObject(obj);
|
||||
_scenes[level]->selectionObjectsView.selectObject(obj);
|
||||
_mapHandler->invalidate(obj);
|
||||
@ -521,7 +521,7 @@ void MapController::commitObjectCreate(int level)
|
||||
|
||||
newObj->pos = pos;
|
||||
|
||||
Initializer init(newObj, defaultPlayer);
|
||||
Initializer init(*this, newObj, defaultPlayer);
|
||||
|
||||
_map->getEditManager()->insertObject(newObj);
|
||||
_mapHandler->invalidate(newObj);
|
||||
|
Loading…
x
Reference in New Issue
Block a user