Explorar el Código

Refactor CArtPlace + use it for commanders

dydzio hace 9 años
padre
commit
baeb3c9e55

+ 1 - 1
client/CPlayerInterface.cpp

@@ -2540,7 +2540,7 @@ void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
 			                 al.slot.num);
 			return;
 		}
-		CArtPlace::askToAssemble(art, al.slot, hero);
+		CHeroArtPlace::askToAssemble(art, al.slot, hero);
 	}
 }
 

+ 108 - 28
client/widgets/CArtifactHolder.cpp

@@ -31,15 +31,13 @@
  *
  */
 
-CArtPlace::CArtPlace(Point position, const CArtifactInstance * Art):
-	locked(false), picked(false), marked(false), ourArt(Art)
+CHeroArtPlace::CHeroArtPlace(Point position, const CArtifactInstance * Art): CArtPlace(position, Art),
+	locked(false), picked(false), marked(false)
 {
-	pos += position;
-	pos.w = pos.h = 44;
 	createImage();
 }
 
-void CArtPlace::createImage()
+void CHeroArtPlace::createImage()
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 
@@ -57,7 +55,7 @@ void CArtPlace::createImage()
 	selection->disable();
 }
 
-void CArtPlace::lockSlot(bool on)
+void CHeroArtPlace::lockSlot(bool on)
 {
 	if (locked == on)
 		return;
@@ -70,7 +68,7 @@ void CArtPlace::lockSlot(bool on)
 		image->setFrame(ourArt->artType->iconIndex);
 }
 
-void CArtPlace::pickSlot(bool on)
+void CHeroArtPlace::pickSlot(bool on)
 {
 	if (picked == on)
 		return;
@@ -82,7 +80,7 @@ void CArtPlace::pickSlot(bool on)
 		image->enable();
 }
 
-void CArtPlace::selectSlot(bool on)
+void CHeroArtPlace::selectSlot(bool on)
 {
 	if (marked == on)
 		return;
@@ -94,7 +92,7 @@ void CArtPlace::selectSlot(bool on)
 		selection->disable();
 }
 
-void CArtPlace::clickLeft(tribool down, bool previousState)
+void CHeroArtPlace::clickLeft(tribool down, bool previousState)
 {
 	//LRClickableAreaWTextComp::clickLeft(down);
 	bool inBackpack = slotID >= GameConstants::BACKPACK_START,
@@ -211,7 +209,7 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
 	}
 }
 
-bool CArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition slot,
+bool CHeroArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition slot,
                               const CGHeroInstance *hero)
 {
 	assert(art != nullptr);
@@ -239,7 +237,7 @@ bool CArtPlace::askToAssemble(const CArtifactInstance *art, ArtifactPosition slo
 	return false;
 }
 
-void CArtPlace::clickRight(tribool down, bool previousState)
+void CHeroArtPlace::clickRight(tribool down, bool previousState)
 {
 	if(down && ourArt && !locked && text.size() && !picked)  //if there is no description or it's a lock, do nothing ;]
 	{
@@ -277,7 +275,7 @@ void CArtPlace::clickRight(tribool down, bool previousState)
 /**
  * Selects artifact slot so that the containing artifact looks like it's picked up.
  */
-void CArtPlace::select ()
+void CHeroArtPlace::select ()
 {
 	if (locked)
 		return;
@@ -288,7 +286,7 @@ void CArtPlace::select ()
 	{
 		for(int i = 0; i < GameConstants::BACKPACK_START; i++)
 		{
-			CArtPlace * ap = ourOwner->getArtPlace(i);
+			CHeroArtPlace * ap = ourOwner->getArtPlace(i);
 			if(nullptr != ap)//getArtPlace may return null
 				ap->pickSlot(ourArt->isPart(ap->ourArt));
 		}
@@ -308,7 +306,7 @@ void CArtPlace::select ()
 /**
  * Deselects the artifact slot.
  */
-void CArtPlace::deselect ()
+void CHeroArtPlace::deselect ()
 {
 	pickSlot(false);
 	if(ourArt && ourArt->canBeDisassembled()) //combined art returned to its slot -> restore locks
@@ -333,7 +331,7 @@ void CArtPlace::deselect ()
 	ourOwner->safeRedraw();
 }
 
-void CArtPlace::showAll(SDL_Surface * to)
+void CHeroArtPlace::showAll(SDL_Surface * to)
 {
 	if (ourArt && !picked && ourArt == ourOwner->curHero->getArt(slotID, false)) //last condition is needed for disassembling -> artifact may be gone, but we don't know yet TODO: real, nice solution
 	{
@@ -358,7 +356,7 @@ void CArtPlace::showAll(SDL_Surface * to)
 	}
 }
 
-bool CArtPlace::fitsHere(const CArtifactInstance * art) const
+bool CHeroArtPlace::fitsHere(const CArtifactInstance * art) const
 {
 	// You can place 'no artifact' anywhere.
 	if(!art)
@@ -371,12 +369,12 @@ bool CArtPlace::fitsHere(const CArtifactInstance * art) const
 	return art->canBePutAt(ArtifactLocation(ourOwner->curHero, slotID), true);
 }
 
-void CArtPlace::setMeAsDest(bool backpackAsVoid /*= true*/)
+void CHeroArtPlace::setMeAsDest(bool backpackAsVoid /*= true*/)
 {
 	ourOwner->commonInfo->dst.setTo(this, backpackAsVoid);
 }
 
-void CArtPlace::setArtifact(const CArtifactInstance *art)
+void CHeroArtPlace::setArtifact(const CArtifactInstance *art)
 {
 	baseType = -1; //by default we don't store any component
 	ourArt = art;
@@ -544,7 +542,7 @@ void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw /*= true*/)
 {
 	for(auto p : artWorn)
 		p.second->selectSlot(false);
-	for(CArtPlace *place : backpack)
+	for(CHeroArtPlace *place : backpack)
 		place->selectSlot(false);
 
 	if(withRedraw)
@@ -554,7 +552,7 @@ void CArtifactsOfHero::unmarkLocalSlots(bool withRedraw /*= true*/)
 /**
  * Assigns an artifacts to an artifact place depending on it's new slot ID.
  */
-void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, ArtifactPosition slotID)
+void CArtifactsOfHero::setSlotData(CHeroArtPlace* artPlace, ArtifactPosition slotID)
 {
 	if(!artPlace && slotID >= GameConstants::BACKPACK_START) //spurious call from artifactMoved in attempt to update hidden backpack slot
 	{
@@ -576,14 +574,14 @@ void CArtifactsOfHero::setSlotData(CArtPlace* artPlace, ArtifactPosition slotID)
 /**
  * Makes given artifact slot appear as empty with a certain slot ID.
  */
-void CArtifactsOfHero::eraseSlotData (CArtPlace* artPlace, ArtifactPosition slotID)
+void CArtifactsOfHero::eraseSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID)
 {
 	artPlace->pickSlot(false);
 	artPlace->slotID = slotID;
 	artPlace->setArtifact(nullptr);
 }
 
-CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CArtPlace *> ArtWorn, std::vector<CArtPlace *> Backpack,
+CArtifactsOfHero::CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack,
 	CButton *leftScroll, CButton *rightScroll, bool createCommonPart):
 
 	curHero(nullptr),
@@ -642,7 +640,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
 	// Create slots for worn artifacts.
 	for (size_t g = 0; g < GameConstants::BACKPACK_START ; g++)
 	{
-		artWorn[ArtifactPosition(g)] = new CArtPlace(slotPos[g]);
+		artWorn[ArtifactPosition(g)] = new CHeroArtPlace(slotPos[g]);
 		artWorn[ArtifactPosition(g)]->ourOwner = this;
 		eraseSlotData(artWorn[ArtifactPosition(g)], ArtifactPosition(g));
 	}
@@ -650,7 +648,7 @@ CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart
 	// Create slots for the backpack.
 	for(size_t s=0; s<5; ++s)
 	{
-		auto add = new CArtPlace(Point(403 + 46 * s, 365));
+		auto add = new CHeroArtPlace(Point(403 + 46 * s, 365));
 
 		add->ourOwner = this;
 		eraseSlotData(add, ArtifactPosition(GameConstants::BACKPACK_START + s));
@@ -750,7 +748,7 @@ void CArtifactsOfHero::artifactMoved(const ArtifactLocation &src, const Artifact
 		assert(dst.slot >= GameConstants::BACKPACK_START);
 		commonInfo->reset();
 
-		CArtPlace *ap = nullptr;
+		CHeroArtPlace *ap = nullptr;
 		for(CArtifactsOfHero *aoh : commonInfo->participants)
 		{
 			if(dst.isHolder(aoh->curHero))
@@ -815,7 +813,7 @@ void CArtifactsOfHero::artifactRemoved(const ArtifactLocation &al)
 	}
 }
 
-CArtPlace * CArtifactsOfHero::getArtPlace(int slot)
+CHeroArtPlace * CArtifactsOfHero::getArtPlace(int slot)
 {
 	if(slot < GameConstants::BACKPACK_START)
 	{
@@ -829,7 +827,7 @@ CArtPlace * CArtifactsOfHero::getArtPlace(int slot)
 	}
 	else
 	{
-		for(CArtPlace *ap : backpack)
+		for(CHeroArtPlace *ap : backpack)
 			if(ap->slotID == slot)
 				return ap;
 		return nullptr;
@@ -919,7 +917,7 @@ CArtifactsOfHero::SCommonPart::Artpos::Artpos()
 	clear();
 }
 
-void CArtifactsOfHero::SCommonPart::Artpos::setTo(const CArtPlace *place, bool dontTakeBackpack)
+void CArtifactsOfHero::SCommonPart::Artpos::setTo(const CHeroArtPlace *place, bool dontTakeBackpack)
 {
 	slotID = place->slotID;
 	AOH = place->ourOwner;
@@ -945,3 +943,85 @@ bool CArtifactsOfHero::SCommonPart::Artpos::valid()
 	assert(AOH && art);
 	return art == AOH->curHero->getArt(slotID);
 }
+
+CArtPlace::CArtPlace(Point position, const CArtifactInstance * Art) : ourArt(Art)
+{
+	pos += position;
+	pos.w = pos.h = 44;
+}
+
+void CArtPlace::clickLeft(tribool down, bool previousState)
+{
+	LRClickableAreaWTextComp::clickLeft(down, previousState);
+}
+
+void CArtPlace::clickRight(tribool down, bool previousState)
+{
+	LRClickableAreaWTextComp::clickRight(down, previousState);
+}
+
+CCommanderArtPlace::CCommanderArtPlace(Point position, const CArtifactInstance * Art) : CArtPlace(position, Art)
+{
+	createImage();
+	setArtifact(Art);
+}
+
+void CCommanderArtPlace::clickLeft(tribool down, bool previousState)
+{
+	if(ourArt && text.size())
+		CArtPlace::clickLeft(down, previousState);	
+}
+
+void CCommanderArtPlace::clickRight(tribool down, bool previousState)
+{
+	if (down && ourArt && text.size())
+		CArtPlace::clickRight(down, previousState);
+}
+
+void CCommanderArtPlace::createImage()
+{
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+
+	int graphic = 0;
+	if (ourArt)
+		graphic = ourArt->artType->iconIndex;
+
+	image = new CAnimImage("artifact", graphic);
+	if (!ourArt)
+		image->disable();
+}
+
+void CCommanderArtPlace::setArtifact(const CArtifactInstance * art)
+{
+	baseType = -1; //by default we don't store any component
+	ourArt = art;
+	if (!art)
+	{
+		image->disable();
+		text = std::string();
+		return;
+	}
+
+	image->enable();
+	image->setFrame(art->artType->iconIndex);
+
+	text = art->getEffectiveDescription();
+
+	if (art->artType->id == ArtifactID::SPELL_SCROLL)
+	{
+		int spellID = art->getGivenSpellID();
+		if (spellID >= 0)
+		{
+			//add spell component info (used to provide a pic in r-click popup)
+			baseType = CComponent::spell;
+			type = spellID;
+			bonusValue = 0;
+		}
+	}
+	else
+	{
+		baseType = CComponent::artifact;
+		type = art->artType->id;
+		bonusValue = 0;
+	}
+}

+ 43 - 17
client/widgets/CArtifactHolder.h

@@ -41,13 +41,40 @@ public:
 	void artifactAssembled(const ArtifactLocation &artLoc) override;
 };
 
-/// Artifacts can be placed there. Gets shown at the hero window
-class CArtPlace: public LRClickableAreaWTextComp
+class CArtPlace : public LRClickableAreaWTextComp
 {
+protected:
 	CAnimImage *image;
+	virtual void createImage()=0;
+public:
+	const CArtifactInstance * ourArt; // should be changed only with setArtifact()
+
+	CArtPlace(Point position, const CArtifactInstance * Art = nullptr); //c-tor
+	void clickLeft(tribool down, bool previousState) override;
+	void clickRight(tribool down, bool previousState) override;
+
+	virtual void setArtifact(const CArtifactInstance *art)=0;
+};
+
+class CCommanderArtPlace : public CArtPlace
+{
+protected:
+	void createImage() override;
+public:
+	CCommanderArtPlace(Point position, const CArtifactInstance * Art = nullptr); //c-tor
+	void clickLeft(tribool down, bool previousState) override;
+	void clickRight(tribool down, bool previousState) override;
+
+	virtual void setArtifact(const CArtifactInstance * art) override;
+
+};
+
+/// Artifacts can be placed there. Gets shown at the hero window
+class CHeroArtPlace: public CArtPlace
+{
 	CAnimImage *selection;
 
-	void createImage();
+	void createImage() override;
 
 public:
 	// consider these members as const - change them only with appropriate methods e.g. lockSlot()
@@ -62,18 +89,17 @@ public:
 	void selectSlot(bool on);
 
 	CArtifactsOfHero * ourOwner;
-	const CArtifactInstance * ourArt; // should be changed only with setArtifact()
 
-	CArtPlace(Point position, const CArtifactInstance * Art = nullptr); //c-tor
+	CHeroArtPlace(Point position, const CArtifactInstance * Art = nullptr); //c-tor
 	void clickLeft(tribool down, bool previousState) override;
 	void clickRight(tribool down, bool previousState) override;
-	void select ();
-	void deselect ();
+	void select();
+	void deselect();
 	void showAll(SDL_Surface * to) override;
 	bool fitsHere (const CArtifactInstance * art) const; //returns true if given artifact can be placed here
 
 	void setMeAsDest(bool backpackAsVoid = true);
-	void setArtifact(const CArtifactInstance *art);
+	void setArtifact(const CArtifactInstance *art) override;
 	static bool askToAssemble(const CArtifactInstance *art, ArtifactPosition slot,
 	                          const CGHeroInstance *hero);
 };
@@ -83,9 +109,9 @@ class CArtifactsOfHero : public CIntObject
 {
 	const CGHeroInstance * curHero;
 
-	std::map<ArtifactPosition, CArtPlace *> artWorn;
+	std::map<ArtifactPosition, CHeroArtPlace *> artWorn;
 
-	std::vector<CArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
+	std::vector<CHeroArtPlace *> backpack; //hero's visible backpack (only 5 elements!)
 	int backpackPos; //number of first art visible in backpack (in hero's vector)
 
 public:
@@ -99,7 +125,7 @@ public:
 
 			Artpos();
 			void clear();
-			void setTo(const CArtPlace *place, bool dontTakeBackpack);
+			void setTo(const CHeroArtPlace *place, bool dontTakeBackpack);
 			bool valid();
 			bool operator==(const ArtifactLocation &al) const;
 		} src, dst;
@@ -115,14 +141,14 @@ public:
 	CButton * leftArtRoll, * rightArtRoll;
 	bool allowedAssembling;
 	std::multiset<const CArtifactInstance*> artifactsOnAltar; //artifacts id that are technically present in backpack but in GUI are moved to the altar - they'll be omitted in backpack slots
-	std::function<void(CArtPlace*)> highlightModeCallback; //if set, clicking on art place doesn't pick artifact but highlights the slot and calls this function
+	std::function<void(CHeroArtPlace*)> highlightModeCallback; //if set, clicking on art place doesn't pick artifact but highlights the slot and calls this function
 
 	void realizeCurrentTransaction(); //calls callback with parameters stored in commonInfo
 	void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst);
 	void artifactRemoved(const ArtifactLocation &al);
 	void artifactAssembled(const ArtifactLocation &al);
 	void artifactDisassembled(const ArtifactLocation &al);
-	CArtPlace *getArtPlace(int slot);//may return null
+	CHeroArtPlace *getArtPlace(int slot);//may return null
 
 	void setHero(const CGHeroInstance * hero);
 	const CGHeroInstance *getHero() const;
@@ -133,17 +159,17 @@ public:
 	void markPossibleSlots(const CArtifactInstance* art);
 	void unmarkSlots(bool withRedraw = true); //unmarks slots in all visible AOHs
 	void unmarkLocalSlots(bool withRedraw = true); //unmarks slots in that particular AOH
-	void setSlotData (CArtPlace* artPlace, ArtifactPosition slotID);
+	void setSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
 	void updateWornSlots (bool redrawParent = true);
 
 	void updateSlot(ArtifactPosition i);
-	void eraseSlotData (CArtPlace* artPlace, ArtifactPosition slotID);
+	void eraseSlotData (CHeroArtPlace* artPlace, ArtifactPosition slotID);
 
 	CArtifactsOfHero(const Point& position, bool createCommonPart = false);
 	//Alternative constructor, used if custom artifacts positioning required (Kingdom interface)
-	CArtifactsOfHero(std::map<ArtifactPosition, CArtPlace *> ArtWorn, std::vector<CArtPlace *> Backpack,
+	CArtifactsOfHero(std::map<ArtifactPosition, CHeroArtPlace *> ArtWorn, std::vector<CHeroArtPlace *> Backpack,
 		CButton *leftScroll, CButton *rightScroll, bool createCommonPart = false);
 	~CArtifactsOfHero(); //d-tor
 	void updateParentWindow();
-	friend class CArtPlace;
+	friend class CHeroArtPlace;
 };

+ 3 - 2
client/windows/CCreatureWindow.cpp

@@ -4,6 +4,7 @@
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../widgets/Buttons.h"
+#include "../widgets/CArtifactHolder.h"
 #include "../widgets/CComponent.h"
 #include "../widgets/Images.h"
 #include "../widgets/TextControls.h"
@@ -456,11 +457,11 @@ void CStackWindow::CWindowSection::createCommander()
 	{
 		return Point(269 + 47 * (index % 3), 22 + 47 * (index / 3));
 	};
-
 	for (auto equippedArtifact : parent->info->commander->artifactsWorn)
 	{
 		Point artPos = getArtifactPos(equippedArtifact.first);
-		auto icon = new CClickableObject(new CAnimImage("artifact", equippedArtifact.second.artifact.get()->artType.get()->iconIndex, 0, artPos.x, artPos.y), [=] {});
+		//auto icon = new CClickableObject(new CAnimImage("artifact", equippedArtifact.second.artifact.get()->artType.get()->iconIndex, 0, artPos.x, artPos.y), [=] {});
+		auto icon = new CCommanderArtPlace(artPos, equippedArtifact.second.artifact);
 
 		//TODO: Use CArtPlace or equivalent instead of CClickableObject and handle commander artifact actions to match WOG (return artifact to hero etc.)
 	}

+ 1 - 1
client/windows/CHeroWindow.h

@@ -93,6 +93,6 @@ public:
 	virtual void updateGarrisons() override;  //updates the morale widget and calls the parent
 
 	//friends
-	friend void CArtPlace::clickLeft(tribool down, bool previousState);
+	friend void CHeroArtPlace::clickLeft(tribool down, bool previousState);
 	friend class CPlayerInterface;
 };

+ 5 - 5
client/windows/CKingdomInterface.cpp

@@ -828,7 +828,7 @@ class ArtSlotsTab : public CIntObject
 {
 public:
 	CAnimImage * background;
-	std::vector<CArtPlace*> arts;
+	std::vector<CHeroArtPlace*> arts;
 
 	ArtSlotsTab()
 	{
@@ -836,7 +836,7 @@ public:
 		background = new CAnimImage("OVSLOT", 4);
 		pos = background->pos;
 		for (size_t i=0; i<9; i++)
-			arts.push_back(new CArtPlace(Point(270+i*48, 65)));
+			arts.push_back(new CHeroArtPlace(Point(270+i*48, 65)));
 	}
 };
 
@@ -844,7 +844,7 @@ class BackpackTab : public CIntObject
 {
 public:
 	CAnimImage * background;
-	std::vector<CArtPlace*> arts;
+	std::vector<CHeroArtPlace*> arts;
 	CButton *btnLeft;
 	CButton *btnRight;
 
@@ -856,7 +856,7 @@ public:
 		btnLeft = new CButton(Point(269, 66), "HSBTNS3", CButton::tooltip(), 0);
 		btnRight = new CButton(Point(675, 66), "HSBTNS5", CButton::tooltip(), 0);
 		for (size_t i=0; i<8; i++)
-			arts.push_back(new CArtPlace(Point(295+i*48, 65)));
+			arts.push_back(new CHeroArtPlace(Point(295+i*48, 65)));
 	}
 };
 
@@ -882,7 +882,7 @@ CHeroItem::CHeroItem(const CGHeroInstance* Hero):
 	assert(arts1->arts.size() == 9);
 	assert(arts2->arts.size() == 9);	
 	
-	std::map<ArtifactPosition, CArtPlace*> arts = 
+	std::map<ArtifactPosition, CHeroArtPlace*> arts = 
 	{
 		{ArtifactPosition::HEAD, arts1->arts[0]}, 
 		{ArtifactPosition::SHOULDERS,arts1->arts[1]}, 

+ 1 - 1
client/windows/CTradeWindow.cpp

@@ -625,7 +625,7 @@ void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
 	GH.pushInt(nwindow);
 }
 
-void CTradeWindow::artifactSelected(CArtPlace *slot)
+void CTradeWindow::artifactSelected(CHeroArtPlace *slot)
 {
 	assert(mode == EMarketMode::ARTIFACT_RESOURCE);
 	items[1][0]->setArtInstance(slot->ourArt);

+ 1 - 1
client/windows/CTradeWindow.h

@@ -86,7 +86,7 @@ public:
 	void getEmptySlots(std::set<CTradeableItem *> &toRemove);
 	void setMode(EMarketMode::EMarketMode Mode); //mode setter
 
-	void artifactSelected(CArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot
+	void artifactSelected(CHeroArtPlace *slot); //used when selling artifacts -> called when user clicked on artifact slot
 
 	virtual void getBaseForPositions(EType type, int &dx, int &dy, int &x, int &y, int &h, int &w, bool Right, int &leftToRightOffset) const = 0;
 	virtual void selectionChanged(bool side) = 0; //true == left