1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
/*
* CArtifactHolder.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "MiscWidgets.h"
class CArtifactsOfHero;
class CAnimImage;
class CButton;
struct ArtifactLocation;
class CArtifactHolder
{
public:
CArtifactHolder();
virtual void artifactRemoved(const ArtifactLocation &artLoc)=0;
virtual void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)=0;
virtual void artifactDisassembled(const ArtifactLocation &artLoc)=0;
virtual void artifactAssembled(const ArtifactLocation &artLoc)=0;
};
class CArtPlace : public LRClickableAreaWTextComp
{
protected:
std::shared_ptr<CAnimImage> image;
virtual void createImage()=0;
public:
const CArtifactInstance * ourArt; // should be changed only with setArtifact()
CArtPlace(Point position, const CArtifactInstance * Art = nullptr);
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:
const CGHeroInstance * commanderOwner;
ArtifactPosition commanderSlotID;
void createImage() override;
void returnArtToHeroCallback();
public:
CCommanderArtPlace(Point position, const CGHeroInstance * commanderOwner, ArtifactPosition artSlot, const CArtifactInstance * Art = nullptr);
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
{
std::shared_ptr<CAnimImage> selection;
void createImage() override;
public:
// consider these members as const - change them only with appropriate methods e.g. lockSlot()
bool locked;
bool picked;
bool marked;
ArtifactPosition slotID; //Arts::EPOS enum + backpack starting from Arts::BACKPACK_START
CArtifactsOfHero * ourOwner;
CHeroArtPlace(Point position, const CArtifactInstance * Art = nullptr);
void lockSlot(bool on);
void pickSlot(bool on);
void selectSlot(bool on);
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
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) override;
static bool askToAssemble(const CArtifactInstance *art, ArtifactPosition slot,
const CGHeroInstance *hero);
};
/// Contains artifacts of hero. Distincts which artifacts are worn or backpacked
class CArtifactsOfHero : public CIntObject
{
public:
using ArtPlacePtr = std::shared_ptr<CHeroArtPlace>;
using ArtPlaceMap = std::map<ArtifactPosition, ArtPlacePtr>;
struct SCommonPart
{
struct Artpos
{
ArtifactPosition slotID;
const CArtifactsOfHero *AOH;
const CArtifactInstance *art;
Artpos();
void clear();
void setTo(const CHeroArtPlace *place, bool dontTakeBackpack);
bool valid();
bool operator==(const ArtifactLocation &al) const;
} src, dst;
std::set<CArtifactsOfHero *> participants; // Needed to mark slots.
void reset();
};
std::shared_ptr<SCommonPart> commonInfo; //when we have more than one CArtifactsOfHero in one window with exchange possibility, we use this (eg. in exchange window); to be provided externally
bool updateState; // Whether the commonInfo should be updated on setHero or not.
std::shared_ptr<CButton> leftArtRoll;
std::shared_ptr<CButton> 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(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);
ArtPlacePtr getArtPlace(int slot);//may return null
void setHero(const CGHeroInstance * hero);
const CGHeroInstance *getHero() const;
void dispose(); //free resources not needed after closing windows and reset state
void scrollBackpack(int dir); //dir==-1 => to left; dir==1 => to right
void safeRedraw();
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 updateWornSlots (bool redrawParent = true);
void updateSlot(ArtifactPosition i);
CArtifactsOfHero(const Point& position, bool createCommonPart = false);
//Alternative constructor, used if custom artifacts positioning required (Kingdom interface)
CArtifactsOfHero(ArtPlaceMap ArtWorn, std::vector<ArtPlacePtr> Backpack,
std::shared_ptr<CButton> leftScroll, std::shared_ptr<CButton> rightScroll, bool createCommonPart = false);
~CArtifactsOfHero();
void updateParentWindow();
friend class CHeroArtPlace;
private:
const CGHeroInstance * curHero;
ArtPlaceMap artWorn;
std::vector<ArtPlacePtr> backpack; //hero's visible backpack (only 5 elements!)
int backpackPos; //number of first art visible in backpack (in hero's vector)
void eraseSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
void setSlotData(ArtPlacePtr artPlace, ArtifactPosition slotID);
};
class CWindowWithArtifacts : public CArtifactHolder
{
std::vector<std::weak_ptr<CArtifactsOfHero>> artSets;
public:
void addSet(std::shared_ptr<CArtifactsOfHero> artSet);
std::shared_ptr<CArtifactsOfHero::SCommonPart> getCommonPart();
void artifactRemoved(const ArtifactLocation &artLoc) override;
void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) override;
void artifactDisassembled(const ArtifactLocation &artLoc) override;
void artifactAssembled(const ArtifactLocation &artLoc) override;
};
|