1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

ArtifactLocation now use ID for artHolder identification part3

This commit is contained in:
SoundSSGood
2023-10-23 19:37:18 +03:00
parent ab2f6abb87
commit 3c5527a222
12 changed files with 87 additions and 104 deletions

View File

@@ -458,7 +458,7 @@ const CStackInstance & CCreatureSet::getStack(const SlotID & slot) const
return *getStackPtr(slot);
}
const CStackInstance * CCreatureSet::getStackPtr(const SlotID & slot) const
CStackInstance * CCreatureSet::getStackPtr(const SlotID & slot) const
{
if(hasStackAtSlot(slot))
return stacks.find(slot)->second;

View File

@@ -253,7 +253,7 @@ public:
void setToArmy(CSimpleArmy &src); //erases all our army and moves stacks from src to us; src MUST NOT be an armed object! WARNING: use it wisely. Or better do not use at all.
const CStackInstance & getStack(const SlotID & slot) const; //stack must exist
const CStackInstance * getStackPtr(const SlotID & slot) const; //if stack doesn't exist, returns nullptr
CStackInstance * getStackPtr(const SlotID & slot) const; //if stack doesn't exist, returns nullptr
const CCreature * getCreature(const SlotID & slot) const; //workaround of map issue;
int getStackCount(const SlotID & slot) const;
TExpType getStackExperience(const SlotID & slot) const;

View File

@@ -966,6 +966,22 @@ const CGObjectInstance * CGameInfoCallback::getObjInstance( ObjectInstanceID oid
return gs->map->objects[oid.num];
}
CArtifactSet * CGameInfoCallback::getArtSet(const ArtifactLocation & loc) const
{
auto hero = const_cast<CGHeroInstance*>(getHero(loc.artHolder));
if(loc.creature.has_value())
{
if(loc.creature.value() == SlotID::COMMANDER_SLOT_PLACEHOLDER)
return hero->commander;
else
return hero->getStackPtr(loc.creature.value());
}
else
{
return hero;
}
}
std::vector<ObjectInstanceID> CGameInfoCallback::getVisibleTeleportObjects(std::vector<ObjectInstanceID> ids, PlayerColor player) const
{
vstd::erase_if(ids, [&](const ObjectInstanceID & id) -> bool

View File

@@ -40,6 +40,8 @@ class CGameState;
class PathfinderConfig;
struct TurnTimerInfo;
struct ArtifactLocation;
class CArtifactSet;
class CArmedInstance;
class CGObjectInstance;
class CGHeroInstance;
@@ -174,6 +176,7 @@ public:
virtual int64_t estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg
virtual const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
virtual const CGObjectInstance * getObjInstance(ObjectInstanceID oid) const;
virtual CArtifactSet * getArtSet(const ArtifactLocation & loc) const;
//virtual const CGObjectInstance * getArmyInstance(ObjectInstanceID oid) const;
//objects

View File

@@ -9,67 +9,34 @@
*/
#pragma once
#include "../ConstTransitivePtr.h"
#include "../constants/EntityIdentifiers.h"
VCMI_LIB_NAMESPACE_BEGIN
class CGHeroInstance;
class CStackInstance;
class CArmedInstance;
class CArtifactSet;
class CBonusSystemNode;
struct ArtSlotInfo;
using TArtHolder = std::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance>>;
struct ArtifactLocation
{
TArtHolder artHolder;//TODO: identify holder by id
ArtifactPosition slot = ArtifactPosition::PRE_FIRST;
ObjectInstanceID artHolder;
ArtifactPosition slot;
std::optional<SlotID> creature;
ArtifactLocation()
: artHolder(ConstTransitivePtr<CGHeroInstance>())
: artHolder(ObjectInstanceID::NONE)
, slot(ArtifactPosition::PRE_FIRST)
, creature(std::nullopt)
{
}
template<typename T>
ArtifactLocation(const T * ArtHolder, ArtifactPosition Slot)
: artHolder(const_cast<T *>(ArtHolder)) //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
, slot(Slot)
{
}
ArtifactLocation(TArtHolder ArtHolder, const ArtifactPosition & Slot)
: artHolder(std::move(std::move(ArtHolder)))
, slot(Slot)
ArtifactLocation(const ObjectInstanceID id, const ArtifactPosition & slot = ArtifactPosition::PRE_FIRST)
: artHolder(id)
, slot(slot)
, creature(std::nullopt)
{
}
template <typename T>
bool isHolder(const T *t) const
{
if(auto ptrToT = std::get<ConstTransitivePtr<T>>(artHolder))
{
return ptrToT == t;
}
return false;
}
DLL_LINKAGE void removeArtifact(); // BE CAREFUL, this operation modifies holder (gs)
DLL_LINKAGE const CArmedInstance *relatedObj() const; //hero or the stack owner
DLL_LINKAGE PlayerColor owningPlayer() const;
DLL_LINKAGE CArtifactSet *getHolderArtSet();
DLL_LINKAGE CBonusSystemNode *getHolderNode();
DLL_LINKAGE CArtifactSet *getHolderArtSet() const;
DLL_LINKAGE const CBonusSystemNode *getHolderNode() const;
DLL_LINKAGE const CArtifactInstance *getArt() const;
DLL_LINKAGE CArtifactInstance *getArt();
DLL_LINKAGE const ArtSlotInfo *getSlot() const;
template <typename Handler> void serialize(Handler &h, const int version)
template <typename Handler> void serialize(Handler & h, const int version)
{
h & artHolder;
h & slot;
h & creature;
}
};

View File

@@ -1656,35 +1656,34 @@ void RebalanceStacks::applyGs(CGameState * gs)
const auto srcHero = dynamic_cast<CGHeroInstance*>(src.army.get());
const auto dstHero = dynamic_cast<CGHeroInstance*>(dst.army.get());
auto srcLoc = ArtifactLocation(srcHero->id, ArtifactPosition::CREATURE_SLOT);
auto dstLoc = ArtifactLocation(dstHero->id, ArtifactPosition::CREATURE_SLOT);
// TODO set creature id !!!
/*if (auto artHere = srcLoc.getArt())
auto srcStack = const_cast<CStackInstance*>(src.getStack());
auto dstStack = const_cast<CStackInstance*>(dst.getStack());
if(auto srcArt = srcStack->getArt(ArtifactPosition::CREATURE_SLOT))
{
if (dstLoc.getArt())
if(auto dstArt = dstStack->getArt(ArtifactPosition::CREATURE_SLOT))
{
auto dstSlot = ArtifactUtils::getArtBackpackPosition(srcHero, dstLoc.getArt()->getTypeId());
auto dstSlot = ArtifactUtils::getArtBackpackPosition(srcHero, dstArt->getTypeId());
if(srcHero && dstSlot != ArtifactPosition::PRE_FIRST)
{
dstLoc.getArt()->move (dstLoc, ArtifactLocation (srcHero, dstSlot));
dstArt->move(*dstStack, ArtifactPosition::CREATURE_SLOT, *srcHero, dstSlot);
}
//else - artifact cna be lost :/
else
{
EraseArtifact ea;
ea.al = dstLoc;
ea.al = ArtifactLocation(dstHero->id, ArtifactPosition::CREATURE_SLOT);
ea.al.creature = dst.slot;
ea.applyGs(gs);
logNetwork->warn("Cannot move artifact! No free slots");
}
artHere->move (srcLoc, dstLoc);
srcArt->move(*srcStack, ArtifactPosition::CREATURE_SLOT, *dstStack, ArtifactPosition::CREATURE_SLOT);
//TODO: choose from dialog
}
else //just move to the other slot before stack gets erased
{
artHere->move (srcLoc, dstLoc);
srcArt->move(*srcStack, ArtifactPosition::CREATURE_SLOT, *dstStack, ArtifactPosition::CREATURE_SLOT);
}
}*/
}
if (stackExp)
{
ui64 totalExp = srcCount * src.army->getStackExperience(src.slot) + dst.army->getStackCount(dst.slot) * dst.army->getStackExperience(dst.slot);
@@ -1757,7 +1756,7 @@ void PutArtifact::applyGs(CGameState *gs)
assert(!art->getParentNodes().empty());
auto hero = gs->getHero(al.artHolder);
assert(hero);
assert(art->canBePutAt(hero, al.slot));
assert(art && art->canBePutAt(hero, al.slot));
art->putAt(*hero, al.slot);
}
@@ -1796,12 +1795,12 @@ void EraseArtifact::applyGs(CGameState *gs)
void MoveArtifact::applyGs(CGameState * gs)
{
auto srcHero = gs->getHero(src.artHolder);
auto dstHero = gs->getHero(dst.artHolder);
auto srcHero = gs->getArtSet(src);
auto dstHero = gs->getArtSet(dst);
assert(srcHero);
assert(dstHero);
auto art = srcHero->getArt(src.slot);
assert(!ArtifactUtils::isSlotEquipment(dst.slot) || !dst.getArt());
assert(art && art->canBePutAt(dstHero, dst.slot));
art->move(*srcHero, src.slot, *dstHero, dst.slot);
}