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

Refactor CArtPlace + use it for commanders

This commit is contained in:
dydzio 2016-11-04 17:54:09 +01:00
parent 08252a1282
commit baeb3c9e55
8 changed files with 163 additions and 56 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -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.)
}

View File

@ -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;
};

View File

@ -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]},

View File

@ -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);

View File

@ -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