1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Partially redone combined artifacts.

This commit is contained in:
Michał W. Urbańczyk 2011-01-22 03:43:20 +00:00
parent 591ba76f69
commit 3fde9e45df
16 changed files with 291 additions and 48 deletions

View File

@ -103,6 +103,8 @@ public:
//artifacts operations //artifacts operations
virtual void artifactPut(const ArtifactLocation &al){}; virtual void artifactPut(const ArtifactLocation &al){};
virtual void artifactRemoved(const ArtifactLocation &al){}; virtual void artifactRemoved(const ArtifactLocation &al){};
virtual void artifactAssembled(const ArtifactLocation &al){};
virtual void artifactDisassembled(const ArtifactLocation &al){};
virtual void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst){}; virtual void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst){};
virtual void heroCreated(const CGHeroInstance*){}; virtual void heroCreated(const CGHeroInstance*){};

View File

@ -2176,6 +2176,16 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
aoh->artifactMoved(src, dst); aoh->artifactMoved(src, dst);
} }
void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
}
void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
}
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting() CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
{ {
spellbookLastPageBattle = spellbokLastPageAdvmap = 0; spellbookLastPageBattle = spellbokLastPageAdvmap = 0;

View File

@ -170,6 +170,8 @@ public:
void artifactPut(const ArtifactLocation &al); void artifactPut(const ArtifactLocation &al);
void artifactRemoved(const ArtifactLocation &al); void artifactRemoved(const ArtifactLocation &al);
void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst); void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst);
void artifactAssembled(const ArtifactLocation &al);
void artifactDisassembled(const ArtifactLocation &al);
void heroCreated(const CGHeroInstance* hero) OVERRIDE; void heroCreated(const CGHeroInstance* hero) OVERRIDE;
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE; void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback) OVERRIDE;

View File

@ -4532,7 +4532,7 @@ CRClickPopupInt::~CRClickPopupInt()
} }
CArtPlace::CArtPlace(const CArtifactInstance* Art) CArtPlace::CArtPlace(const CArtifactInstance* Art)
: marked(false), ourArt(Art), picked(false) : marked(false), ourArt(Art), picked(false), locked(false)
{ {
} }
@ -4647,7 +4647,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
void CArtPlace::clickRight(tribool down, bool previousState) void CArtPlace::clickRight(tribool down, bool previousState)
{ {
if(down && ourArt && !locked() && text.size()) //if there is no description or it's a lock, do nothing ;] if(down && ourArt && !locked && text.size()) //if there is no description or it's a lock, do nothing ;]
{ {
if (slotID < 19) if (slotID < 19)
{ {
@ -4695,7 +4695,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
*/ */
void CArtPlace::select () void CArtPlace::select ()
{ {
if (locked()) if (locked)
return; return;
picked = true; picked = true;
@ -4741,7 +4741,10 @@ void CArtPlace::deactivate()
void CArtPlace::showAll(SDL_Surface *to) void CArtPlace::showAll(SDL_Surface *to)
{ {
if (ourArt && !picked) if (ourArt && !picked)
blitAt(graphics->artDefs->ourImages[ourArt->artType->id].bitmap, pos.x, pos.y, to); {
int graphic = locked ? 145 : ourArt->artType->id;
blitAt(graphics->artDefs->ourImages[graphic].bitmap, pos.x, pos.y, to);
}
if(marked && active) if(marked && active)
{ {
@ -4779,11 +4782,6 @@ CArtPlace::~CArtPlace()
deactivate(); deactivate();
} }
bool CArtPlace::locked() const
{
return ourArt && ourArt->id == 145;
}
void CArtPlace::setMeAsDest(bool backpackAsVoid /*= true*/) void CArtPlace::setMeAsDest(bool backpackAsVoid /*= true*/)
{ {
ourOwner->commonInfo->dst.setTo(this, backpackAsVoid); ourOwner->commonInfo->dst.setTo(this, backpackAsVoid);
@ -4800,7 +4798,7 @@ void CArtPlace::setArtifact(const CArtifactInstance *art)
else else
{ {
text = ourArt->artType->Description(); text = ourArt->artType->Description();
if (locked()) // Locks should appear as empty. if (locked) // Locks should appear as empty.
hoverText = CGI->generaltexth->allTexts[507]; hoverText = CGI->generaltexth->allTexts[507];
else else
hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % ourArt->artType->Name()); hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[1]) % ourArt->artType->Name());
@ -5113,7 +5111,14 @@ void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, int slotID)
artPlace->picked = false; artPlace->picked = false;
artPlace->slotID = slotID; artPlace->slotID = slotID;
artPlace->setArtifact(curHero->getArt(slotID));
if(const ArtSlotInfo *asi = curHero->getSlot(slotID))
{
artPlace->setArtifact(asi->artifact);
artPlace->locked = asi->locked;
}
else
artPlace->setArtifact(NULL);
} }
/** /**

View File

@ -925,6 +925,7 @@ public:
bool picked; bool picked;
bool marked; bool marked;
bool locked;
CArtifactsOfHero * ourOwner; CArtifactsOfHero * ourOwner;
const CArtifactInstance * ourArt; const CArtifactInstance * ourArt;
@ -937,7 +938,6 @@ public:
void deactivate(); void deactivate();
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
bool fitsHere (const CArtifactInstance * art) const; //returns true if given artifact can be placed here bool fitsHere (const CArtifactInstance * art) const; //returns true if given artifact can be placed here
bool locked () const;
void setMeAsDest(bool backpackAsVoid = true); void setMeAsDest(bool backpackAsVoid = true);
void setArtifact(const CArtifactInstance *art); void setArtifact(const CArtifactInstance *art);

View File

@ -184,6 +184,20 @@ void MoveArtifact::applyCl( CClient *cl )
INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst); INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
} }
void AssembledArtifact::applyCl( CClient *cl )
{
// INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
// if(src.hero->tempOwner != dst.hero->tempOwner)
// INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
}
void DisassembledArtifact::applyCl( CClient *cl )
{
// INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
// if(src.hero->tempOwner != dst.hero->tempOwner)
// INTERFACE_CALL_IF_PRESENT(src.hero->tempOwner, artifactMoved, src, dst);
}
void GiveBonus::applyCl( CClient *cl ) void GiveBonus::applyCl( CClient *cl )
{ {
switch(who) switch(who)

View File

@ -547,6 +547,12 @@ t1 & abetw(t1 &a, const t2 &b, const t3 &c) //makes a to fit the range <b, c>
return a; return a;
} }
template <typename t1, typename t2, typename t3>
bool isbetw(const t1 &a, const t2 &b, const t3 &c) //checks if a is between b and c
{
return a > b && a < c;
}
template <typename T> template <typename T>
void delNull(T* &ptr) //deleted pointer and sets it to NULL void delNull(T* &ptr) //deleted pointer and sets it to NULL
{ {

View File

@ -951,13 +951,7 @@ void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
{ {
assert(canBePutAt(ArtifactLocation(h, slot))); assert(canBePutAt(ArtifactLocation(h, slot)));
ArtSlotInfo &asi = slot < Arts::BACKPACK_START h->setNewArtSlot(slot, this, false);
? h->artifactsWorn[slot]
: *h->artifactsInBackpack.insert(h->artifactsInBackpack.begin() + (slot - Arts::BACKPACK_START), ArtSlotInfo());
asi.artifact = this;
asi.locked = false;
if(slot < Arts::BACKPACK_START) if(slot < Arts::BACKPACK_START)
h->attachTo(this); h->attachTo(this);
} }
@ -965,16 +959,9 @@ void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot) void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
{ {
assert(h->CArtifactSet::getArt(slot) == this); assert(h->CArtifactSet::getArt(slot) == this);
h->eraseArtSlot(slot);
if(slot < Arts::BACKPACK_START) if(slot < Arts::BACKPACK_START)
{
h->artifactsWorn.erase(slot);
h->detachFrom(this); h->detachFrom(this);
}
else
{
slot -= Arts::BACKPACK_START;
h->artifactsInBackpack.erase(h->artifactsInBackpack.begin() + slot);
}
//TODO delete me? //TODO delete me?
} }
@ -1024,7 +1011,11 @@ CArtifactInstance * CArtifactInstance::createNewArtifactInstance(CArtifact *Art)
if(!Art->constituents) if(!Art->constituents)
return new CArtifactInstance(Art); return new CArtifactInstance(Art);
else else
return new CCombinedArtifactInstance(Art); {
CCombinedArtifactInstance * ret = new CCombinedArtifactInstance(Art);
ret->createConstituents();
return ret;
}
} }
CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid) CArtifactInstance * CArtifactInstance::createNewArtifactInstance(int aid)
@ -1060,10 +1051,96 @@ void CCombinedArtifactInstance::createConstituents()
BOOST_FOREACH(ui32 a, *artType->constituents) BOOST_FOREACH(ui32 a, *artType->constituents)
{ {
constituentsInfo.push_back(ConstituentInfo(CArtifactInstance::createNewArtifactInstance(a))); addAsConstituent(CArtifactInstance::createNewArtifactInstance(a), -1);
} }
} }
void CCombinedArtifactInstance::addAsConstituent(CArtifactInstance *art, int slot)
{
assert(vstd::contains(*artType->constituents, art->artType->id));
assert(art->parents.size() == 1 && art->parents.front() == art->artType);
constituentsInfo.push_back(ConstituentInfo(art, slot));
art->attachTo(this);
}
void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
{
if(slot >= Arts::BACKPACK_START)
{
CArtifactInstance::putAt(h, slot);
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
ci.slot = -1;
}
else
{
CArtifactInstance *mainConstituent = figureMainConstituent(slot); //it'll be replaced with combined artifact, not a lock
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
{
if(ci.art != mainConstituent)
{
int pos = -1;
if(isbetw(ci.slot, 0, Arts::BACKPACK_START) && ci.art->canBePutAt(ArtifactLocation(h, ci.slot))) //there is a valid suggestion where to place lock
pos = ci.slot;
else
ci.slot = pos = ci.art->firstAvailableSlot(h);
assert(pos < Arts::BACKPACK_START);
h->setNewArtSlot(pos, ci.art, true); //sets as lock
}
else
{
ci.slot = -1;
CArtifactInstance::putAt(h, slot); //puts combined art (this)
}
}
}
}
void CCombinedArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
{
if(slot >= Arts::BACKPACK_START)
{
CArtifactInstance::removeFrom(h, slot);
}
else
{
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
{
if(ci.slot >= 0)
{
h->eraseArtSlot(ci.slot);
ci.slot = -1;
}
else
{
//main constituent
CArtifactInstance::removeFrom(h, slot);
}
}
}
}
CArtifactInstance * CCombinedArtifactInstance::figureMainConstituent(ui16 slot)
{
CArtifactInstance *mainConstituent = NULL; //it'll be replaced with combined artifact, not a lock
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
if(ci.slot == slot)
mainConstituent = ci.art;
if(!mainConstituent)
{
BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
{
if(vstd::contains(ci.art->artType->possibleSlots, slot))
{
mainConstituent = ci.art;
}
}
}
return mainConstituent;
}
CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/) CCombinedArtifactInstance::ConstituentInfo::ConstituentInfo(CArtifactInstance *Art /*= NULL*/, ui16 Slot /*= -1*/)
{ {

View File

@ -81,10 +81,10 @@ public:
virtual bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const; virtual bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const;
virtual bool canBeDisassembled() const; virtual bool canBeDisassembled() const;
std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const; virtual void putAt(CGHeroInstance *h, ui16 slot);
virtual void removeFrom(CGHeroInstance *h, ui16 slot);
void putAt(CGHeroInstance *h, ui16 slot); std::vector<const CArtifact *> assemblyPossibilities(const CGHeroInstance *h) const;
void removeFrom(CGHeroInstance *h, ui16 slot);
void move(ArtifactLocation &src, ArtifactLocation &dst); void move(ArtifactLocation &src, ArtifactLocation &dst);
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
@ -118,11 +118,17 @@ public:
bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE; bool canBePutAt(const ArtifactLocation &al, bool assumeDestRemoved = false) const OVERRIDE;
bool canBeDisassembled() const OVERRIDE; bool canBeDisassembled() const OVERRIDE;
void putAt(CGHeroInstance *h, ui16 slot) OVERRIDE;
void removeFrom(CGHeroInstance *h, ui16 slot) OVERRIDE;
void createConstituents();
void addAsConstituent(CArtifactInstance *art, int slot);
CArtifactInstance *figureMainConstituent(ui16 slot); //main constituent is replcaed with us (combined art), not lock
CCombinedArtifactInstance(); CCombinedArtifactInstance();
void createConstituents();
friend class CArtifactInstance; friend class CArtifactInstance;
friend class AssembledArtifact;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & static_cast<CArtifactInstance&>(*this); h & static_cast<CArtifactInstance&>(*this);

View File

@ -6940,6 +6940,10 @@ const CArtifactInstance* CArtifactSet::getArt(ui16 pos) const
return NULL; return NULL;
} }
CArtifactInstance* CArtifactSet::getArt(ui16 pos)
{
return const_cast<CArtifactInstance*>((const_cast<const CArtifactSet*>(this))->getArt(pos));
}
// if(pos<19) // if(pos<19)
// if(vstd::contains(artifWorn,pos)) // if(vstd::contains(artifWorn,pos))
// return artifWorn.find(pos)->second; // return artifWorn.find(pos)->second;
@ -7024,3 +7028,33 @@ CArtifactSet::~CArtifactSet()
{ {
} }
ArtSlotInfo & CArtifactSet::retreiveNewArtSlot(ui16 slot)
{
assert(!vstd::contains(artifactsWorn, slot));
ArtSlotInfo &ret = slot < Arts::BACKPACK_START
? artifactsWorn[slot]
: *artifactsInBackpack.insert(artifactsInBackpack.begin() + (slot - Arts::BACKPACK_START), ArtSlotInfo());
return ret;
}
void CArtifactSet::setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked)
{
ArtSlotInfo &asi = retreiveNewArtSlot(slot);
asi.artifact = art;
asi.locked = locked;
}
void CArtifactSet::eraseArtSlot(ui16 slot)
{
if(slot < Arts::BACKPACK_START)
{
artifactsWorn.erase(slot);
}
else
{
slot -= Arts::BACKPACK_START;
artifactsInBackpack.erase(artifactsInBackpack.begin() + slot);
}
}

View File

@ -265,8 +265,13 @@ public:
std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag std::vector<ArtSlotInfo> artifactsInBackpack; //hero's artifacts from bag
bmap<ui16, 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 bmap<ui16, 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
ArtSlotInfo &retreiveNewArtSlot(ui16 slot);
void setNewArtSlot(ui16 slot, CArtifactInstance *art, bool locked);
void eraseArtSlot(ui16 slot);
const ArtSlotInfo *getSlot(ui16 pos) const; const ArtSlotInfo *getSlot(ui16 pos) const;
const CArtifactInstance* getArt(ui16 pos) const; //NULL - no artifact const CArtifactInstance* getArt(ui16 pos) const; //NULL - no artifact
CArtifactInstance* getArt(ui16 pos); //NULL - no artifact
si32 getArtPos(int aid, bool onlyWorn = true) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned) si32 getArtPos(int aid, bool onlyWorn = true) const; //looks for equipped artifact with given ID and returns its slot ID or -1 if none(if more than one such artifact lower ID is returned)
si32 getArtPos(const CArtifactInstance *art) const; si32 getArtPos(const CArtifactInstance *art) const;
bool hasArt(ui32 aid, bool onlyWorn = false) const; //checks if hero possess artifact of given id (either in backack or worn) bool hasArt(ui32 aid, bool onlyWorn = false) const; //checks if hero possess artifact of given id (either in backack or worn)

View File

@ -746,6 +746,10 @@ struct StackLocation
struct CGarrisonOperationPack : CPackForClient struct CGarrisonOperationPack : CPackForClient
{ {
}; };
struct CArtifactOperationPack : CPackForClient
{
};
struct ChangeStackCount : CGarrisonOperationPack //521 struct ChangeStackCount : CGarrisonOperationPack //521
{ {
@ -856,7 +860,7 @@ struct ArtifactLocation
} }
}; };
struct PutArtifact : CGarrisonOperationPack //526 struct PutArtifact : CArtifactOperationPack //526
{ {
ArtifactLocation al; ArtifactLocation al;
ConstTransitivePtr<CArtifactInstance> art; ConstTransitivePtr<CArtifactInstance> art;
@ -870,7 +874,7 @@ struct PutArtifact : CGarrisonOperationPack //526
} }
}; };
struct EraseArtifact : CGarrisonOperationPack //527 struct EraseArtifact : CArtifactOperationPack //527
{ {
ArtifactLocation al; ArtifactLocation al;
@ -883,7 +887,7 @@ struct EraseArtifact : CGarrisonOperationPack //527
} }
}; };
struct MoveArtifact : CGarrisonOperationPack //528 struct MoveArtifact : CArtifactOperationPack //528
{ {
ArtifactLocation src, dst; ArtifactLocation src, dst;
@ -896,6 +900,35 @@ struct MoveArtifact : CGarrisonOperationPack //528
} }
}; };
struct AssembledArtifact : CArtifactOperationPack //529
{
ArtifactLocation al; //where assembly will be put
CArtifact *builtArt;
//std::vector<CArtifactInstance *> constituents;
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & al & builtArt/* & constituents*/;
}
};
struct DisassembledArtifact : CArtifactOperationPack //530
{
ArtifactLocation al;
void applyCl(CClient *cl);
DLL_EXPORT void applyGs(CGameState *gs);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & al;
}
};
struct NewTurn : public CPackForClient //101 struct NewTurn : public CPackForClient //101
{ {
enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE}; enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, CUSTOM, NO_ACTION, NONE};

View File

@ -586,8 +586,7 @@ DLL_EXPORT void NewObject::applyGs( CGameState *gs )
DLL_EXPORT void NewArtifact::applyGs( CGameState *gs ) DLL_EXPORT void NewArtifact::applyGs( CGameState *gs )
{ {
assert(!vstd::contains(gs->map->artInstances, art)); assert(!vstd::contains(gs->map->artInstances, art));
art->id = gs->map->artInstances.size(); gs->map->addNewArtifactInstance(art);
gs->map->artInstances.push_back(art);
assert(!art->parents.size()); assert(!art->parents.size());
art->setType(art->artType); art->setType(art->artType);
@ -722,6 +721,34 @@ DLL_EXPORT void MoveArtifact::applyGs( CGameState *gs )
a->move(src, dst); a->move(src, dst);
} }
DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
{
CGHeroInstance *h = al.hero;
const CArtifactInstance *transformedArt = al.getArt();
assert(transformedArt);
assert(vstd::contains(transformedArt->assemblyPossibilities(al.hero), builtArt));
CCombinedArtifactInstance *combinedArt = new CCombinedArtifactInstance(builtArt);
//retreive all constituents
BOOST_FOREACH(si32 constituentID, *builtArt->constituents)
{
int pos = h->getArtPos(constituentID);
assert(pos >= 0);
CArtifactInstance *constituentInstance = h->getArt(pos);
//move constituent from hero to be part of new, combined artifact
constituentInstance->removeFrom(h, pos);
combinedArt->addAsConstituent(constituentInstance, pos);
}
//put new combined artifacts
combinedArt->putAt(h, al.slot);
}
DLL_EXPORT void DisassembledArtifact::applyGs( CGameState *gs )
{
}
DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs ) DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
{ {
if(id >= 0) if(id >= 0)

View File

@ -155,6 +155,8 @@ void registerTypes2(Serializer &s)
s.template registerType<PutArtifact>(); s.template registerType<PutArtifact>();
s.template registerType<EraseArtifact>(); s.template registerType<EraseArtifact>();
s.template registerType<MoveArtifact>(); s.template registerType<MoveArtifact>();
s.template registerType<AssembledArtifact>();
s.template registerType<DisassembledArtifact>();
s.template registerType<SaveGame>(); s.template registerType<SaveGame>();
s.template registerType<SetSelection>(); s.template registerType<SetSelection>();

View File

@ -12,6 +12,7 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <assert.h> #include <assert.h>
#include "CSpellHandler.h" #include "CSpellHandler.h"
#include <boost/foreach.hpp>
/* /*
* map.cpp, part of VCMI engine * map.cpp, part of VCMI engine
@ -1490,9 +1491,9 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
i+=4; i+=4;
innerArt = CArtifactInstance::createScroll(VLC->spellh->spells[spellID]); innerArt = CArtifactInstance::createScroll(VLC->spellh->spells[spellID]);
} }
else if(art->ID == 5) //specific artifact else if(defInfo->id == 5) //specific artifact
{ {
innerArt = createArt(art->subID); innerArt = createArt(defInfo->subid);
} }
else else
{ {
@ -2084,7 +2085,15 @@ CArtifactInstance * Mapa::createArt(int aid)
else else
a = new CArtifactInstance(); a = new CArtifactInstance();
this->addNewArtifactInstance(a); addNewArtifactInstance(a);
if(a->artType && a->artType->constituents) //TODO make it nicer
{
CCombinedArtifactInstance *comb = dynamic_cast<CCombinedArtifactInstance*>(a);
BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, comb->constituentsInfo)
{
addNewArtifactInstance(ci.art);
}
}
return a; return a;
} }

View File

@ -2565,13 +2565,24 @@ bool CGameHandler::moveArtifact(si32 srcHeroID, si32 destHeroID, ui16 srcSlot, u
*/ */
bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo) bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assemble, ui32 assembleTo)
{ {
if (artifactSlot < 0 || artifactSlot > 18) {
complain("Illegal artifact slot.");
return false;
}
CGHeroInstance *hero = gs->getHero(heroID); CGHeroInstance *hero = gs->getHero(heroID);
const CArtifactInstance *destArtifact = hero->getArt(artifactSlot); const CArtifactInstance *destArtifact = hero->getArt(artifactSlot);
if(!destArtifact)
COMPLAIN_RET("assembleArtifacts: there is no such artifact instance!");
CArtifact *combinedArt = VLC->arth->artifacts[assembleTo];
if(!combinedArt->constituents)
COMPLAIN_RET("assembleArtifacts: Artifact being attempted to assemble is not a combined artifacts!");
if(!vstd::contains(destArtifact->assemblyPossibilities(hero), combinedArt))
COMPLAIN_RET("assembleArtifacts: It's impossible to assemble requested artifact!");
AssembledArtifact aa;
aa.al = ArtifactLocation(hero, artifactSlot);
aa.builtArt = combinedArt;
CCombinedArtifactInstance *assembliedArt = new CCombinedArtifactInstance();
/* /*
SetHeroArtifacts sha; SetHeroArtifacts sha;
sha.hid = heroID; sha.hid = heroID;