Bläddra i källkod

Mostly done combined artifacts.
[assembling, disassembling, moving, picking]

Michał W. Urbańczyk 14 år sedan
förälder
incheckning
e6d577c233

+ 8 - 0
client/CPlayerInterface.cpp

@@ -2179,11 +2179,19 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
 void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
+	BOOST_FOREACH(IShowActivable *isa, GH.listInt)
+		if(isa->type & IShowActivable::WITH_ARTIFACTS)
+			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
+				aoh->artifactAssembled(al);
 }
 
 void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 {
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
+	BOOST_FOREACH(IShowActivable *isa, GH.listInt)
+		if(isa->type & IShowActivable::WITH_ARTIFACTS)
+			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
+				aoh->artifactDisassembled(al);
 }
 
 CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()

+ 30 - 5
client/GUIClasses.cpp

@@ -803,6 +803,11 @@ SComponent::SComponent(const Component &c)
 		subtitle += CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2);
 }
 
+SComponent::SComponent()
+{
+	img = NULL;
+}
+
 SComponent::~SComponent()
 {
 	if (free && img)
@@ -4665,7 +4670,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
 						boost::bind(&CCallback::assembleArtifacts, LOCPLINT->cb, ourOwner->curHero, slotID, true, combination->id),
 						0);
 
-					if(assemblyPossibilities.size())
+					if(assemblyPossibilities.size() > 2)
 					{
 						tlog3 << "More than one possibility of assembling... taking only first\n";
 						break;
@@ -5239,12 +5244,12 @@ void CArtifactsOfHero::realizeCurrentTransaction()
 
 void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst)
 {
-	if(src.hero == curHero)
+	if(src.hero == curHero && src.slot >= Arts::BACKPACK_START)
 		setSlotData(getArtPlace(src.slot), src.slot);
-	if(dst.hero == curHero)
+	if(dst.hero == curHero && dst.slot >= Arts::BACKPACK_START)
 		setSlotData(getArtPlace(dst.slot), dst.slot);
-
-	updateParentWindow();
+	if(src.hero == curHero  ||  dst.hero == curHero) //we need to update all slots, artifact might be combined and affect more slots
+		updateWornSlots();
 
 	if(commonInfo->src == src) //artifact was taken from us
 	{
@@ -5313,6 +5318,26 @@ CArtPlace * CArtifactsOfHero::getArtPlace(int slot)
 	return NULL;
 }
 
+void CArtifactsOfHero::artifactAssembled(const ArtifactLocation &al)
+{
+	if(al.hero == curHero)
+		updateWornSlots();
+}
+
+void CArtifactsOfHero::artifactDisassembled(const ArtifactLocation &al)
+{
+	if(al.hero == curHero)
+		updateWornSlots();
+}
+
+void CArtifactsOfHero::updateWornSlots()
+{
+	for(int i = 0; i < Arts::BACKPACK_START; i++)
+		setSlotData(getArtPlace(i), i);
+
+	updateParentWindow();
+}
+
 void CExchangeWindow::close()
 {
 	GH.popIntTotally(this);

+ 4 - 1
client/GUIClasses.h

@@ -170,7 +170,7 @@ public:
 	void init(Etype Type, int Subtype, int Val);
 	SComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur=NULL, bool freeSur=false); //c-tor
 	SComponent(const Component &c); //c-tor
-	SComponent(){}; //c-tor
+	SComponent();; //c-tor
 	virtual ~SComponent(); //d-tor
 
 	void clickRight(tribool down, bool previousState); //call-in
@@ -982,6 +982,8 @@ public:
 
 	void realizeCurrentTransaction(); //calls callback with parameters stored in commonInfo
 	void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst);
+	void artifactAssembled(const ArtifactLocation &al);
+	void artifactDisassembled(const ArtifactLocation &al);
 	CArtPlace *getArtPlace(int slot);
 
 	void setHero(const CGHeroInstance * hero);
@@ -992,6 +994,7 @@ public:
 	void markPossibleSlots(const CArtifactInstance* art);
 	void unmarkSlots(bool withRedraw = true);
 	void setSlotData (CArtPlace* artPlace, int slotID);
+	void updateWornSlots ();
 	void eraseSlotData (CArtPlace* artPlace, int slotID);
 
 	CArtifactsOfHero(const Point& position, bool createCommonPart = false); //c-tor

+ 2 - 6
client/NetPacksClient.cpp

@@ -186,16 +186,12 @@ void MoveArtifact::applyCl( CClient *cl )
 
 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);
+	INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactAssembled, al);
 }
 
 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);
+	INTERFACE_CALL_IF_PRESENT(al.hero->tempOwner, artifactDisassembled, al);
 }
 
 void GiveBonus::applyCl( CClient *cl )

+ 3 - 5
lib/CArtHandler.cpp

@@ -942,9 +942,7 @@ bool CArtifactInstance::canBePutAt(const ArtifactLocation &al, bool assumeDestRe
 	if(!vstd::contains(artType->possibleSlots, al.slot))
 		return false;
 
-	if(!assumeDestRemoved) //test if slot is free
-		return al.hero->isPositionFree(al.slot);
-	return true;
+	return al.hero->isPositionFree(al.slot, assumeDestRemoved);
 }
 
 void CArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
@@ -968,7 +966,7 @@ void CArtifactInstance::removeFrom(CGHeroInstance *h, ui16 slot)
 
 bool CArtifactInstance::canBeDisassembled() const
 {
-	return false;
+	return artType->constituents && artType->constituentOf->size();
 }
 
 std::vector<const CArtifact *> CArtifactInstance::assemblyPossibilities(const CGHeroInstance *h) const
@@ -1074,6 +1072,7 @@ void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
 	else
 	{
 		CArtifactInstance *mainConstituent = figureMainConstituent(slot); //it'll be replaced with combined artifact, not a lock
+		CArtifactInstance::putAt(h, slot); //puts combined art (this)
 
 		BOOST_FOREACH(ConstituentInfo &ci, constituentsInfo)
 		{
@@ -1091,7 +1090,6 @@ void CCombinedArtifactInstance::putAt(CGHeroInstance *h, ui16 slot)
 			else
 			{
 				ci.slot = -1;
-				CArtifactInstance::putAt(h, slot); //puts combined art (this)
 			}
 		}
 	}

+ 2 - 2
lib/CObjectHandler.cpp

@@ -7005,10 +7005,10 @@ const ArtSlotInfo * CArtifactSet::getSlot(ui16 pos) const
 	return NULL;
 }
 
-bool CArtifactSet::isPositionFree(ui16 pos) const
+bool CArtifactSet::isPositionFree(ui16 pos, bool onlyLockCheck /*= false*/) const
 {
 	if(const ArtSlotInfo *s = getSlot(pos))
-		return !s->artifact && !s->locked;
+		return (onlyLockCheck || !s->artifact) && !s->locked;
 
 	return true; //no slot means not used
 }

+ 1 - 1
lib/CObjectHandler.h

@@ -275,7 +275,7 @@ public:
 	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;
 	bool hasArt(ui32 aid, bool onlyWorn = false) const; //checks if hero possess artifact of given id (either in backack or worn)
-	bool isPositionFree(ui16 pos) const;
+	bool isPositionFree(ui16 pos, bool onlyLockCheck = false) const;
 	si32 getArtTypeId(ui16 pos) const;
 
 

+ 13 - 0
lib/NetPacksLib.cpp

@@ -747,6 +747,19 @@ DLL_EXPORT void AssembledArtifact::applyGs( CGameState *gs )
 
 DLL_EXPORT void DisassembledArtifact::applyGs( CGameState *gs )
 {
+	CGHeroInstance *h = al.hero;
+	CCombinedArtifactInstance *disassembled = dynamic_cast<CCombinedArtifactInstance*>(al.getArt());
+	assert(disassembled);
+
+	std::vector<CCombinedArtifactInstance::ConstituentInfo> constituents = disassembled->constituentsInfo;
+	disassembled->removeFrom(h, al.slot);
+	BOOST_FOREACH(CCombinedArtifactInstance::ConstituentInfo &ci, constituents)
+	{
+		ci.art->detachFrom(disassembled);
+		ci.art->putAt(h, ci.slot >= 0 ? ci.slot : al.slot); //-1 is slot of main constituent -> it'll replace combined artifact in its pos
+	}
+
+	delNull(disassembled);
 }
 
 DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )

+ 20 - 9
server/CGameHandler.cpp

@@ -2572,17 +2572,28 @@ bool CGameHandler::assembleArtifacts (si32 heroID, ui16 artifactSlot, bool assem
 	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!");
+	if(assemble)
+	{
+		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;
+		AssembledArtifact aa;
+		aa.al = ArtifactLocation(hero, artifactSlot);
+		aa.builtArt = combinedArt;
+		sendAndApply(&aa);
+	}
+	else
+	{
+		if(!destArtifact->artType->constituents)
+			COMPLAIN_RET("assembleArtifacts: Artifact being attempted to disassemble is not a combined artifact!");
 
-	CCombinedArtifactInstance *assembliedArt = new CCombinedArtifactInstance();
+		DisassembledArtifact da;
+		da.al = ArtifactLocation(hero, artifactSlot);
+		sendAndApply(&da);
+	}
 	/*
 	SetHeroArtifacts sha;
 	sha.hid = heroID;