2014-07-13 16:11:25 +03:00
|
|
|
/*
|
|
|
|
* CGarrisonInt.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
|
|
|
|
*
|
|
|
|
*/
|
2017-07-13 10:26:03 +02:00
|
|
|
#pragma once
|
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
#include "../gui/CIntObject.h"
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2022-07-26 15:07:42 +02:00
|
|
|
VCMI_LIB_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
class CArmedInstance;
|
|
|
|
class CStackInstance;
|
|
|
|
|
|
|
|
VCMI_LIB_NAMESPACE_END
|
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
class CGarrisonInt;
|
2014-08-03 14:16:19 +03:00
|
|
|
class CButton;
|
2014-07-13 16:11:25 +03:00
|
|
|
class CAnimImage;
|
|
|
|
class CLabel;
|
2023-07-06 00:20:44 +02:00
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
enum class EGarrisonType
|
2023-07-06 00:20:44 +02:00
|
|
|
{
|
2023-07-07 00:08:29 +02:00
|
|
|
UPPER, /// up garrison (Garrisoned)
|
|
|
|
LOWER, /// down garrison (Visiting)
|
2023-07-06 00:20:44 +02:00
|
|
|
};
|
2014-07-13 16:11:25 +03:00
|
|
|
|
|
|
|
/// A single garrison slot which holds one creature of a specific amount
|
|
|
|
class CGarrisonSlot : public CIntObject
|
|
|
|
{
|
|
|
|
SlotID ID; //for identification
|
|
|
|
CGarrisonInt *owner;
|
2018-04-07 13:34:11 +02:00
|
|
|
const CStackInstance * myStack; //nullptr if slot is empty
|
|
|
|
const CCreature * creature;
|
2023-07-07 00:08:29 +02:00
|
|
|
EGarrisonType upg;
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2018-04-07 13:34:11 +02:00
|
|
|
std::shared_ptr<CAnimImage> creatureImage;
|
|
|
|
std::shared_ptr<CAnimImage> selectionImage; // image for selection, not always visible
|
|
|
|
std::shared_ptr<CLabel> stackCount;
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2023-07-06 00:20:44 +02:00
|
|
|
public:
|
2015-08-24 22:39:56 +02:00
|
|
|
bool viewInfo();
|
|
|
|
bool highlightOrDropArtifact();
|
|
|
|
bool split();
|
2023-07-07 00:08:29 +02:00
|
|
|
|
|
|
|
/// If certain creates cannot be moved, the selection should change
|
|
|
|
/// Force reselection in these cases
|
|
|
|
/// * When attempting to take creatures from ally
|
|
|
|
/// * When attempting to swap creatures with an ally
|
|
|
|
/// * When attempting to take unremovable units
|
|
|
|
/// @return Whether reselection must be done
|
2015-08-25 00:41:41 +02:00
|
|
|
bool mustForceReselection() const;
|
2015-08-24 22:39:56 +02:00
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
void setHighlight(bool on);
|
2021-11-28 14:57:38 +02:00
|
|
|
std::function<void()> getDismiss() const;
|
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
const CArmedInstance * getObj() const;
|
|
|
|
bool our() const;
|
2021-11-28 21:48:22 +02:00
|
|
|
SlotID getSlot() const { return ID; }
|
2023-07-07 00:08:29 +02:00
|
|
|
EGarrisonType getGarrison() const { return upg; }
|
2015-03-16 01:04:18 +02:00
|
|
|
bool ally() const;
|
2023-07-07 00:08:29 +02:00
|
|
|
|
|
|
|
// CIntObject overrides
|
2023-07-08 13:33:04 +02:00
|
|
|
void showPopupWindow(const Point & cursorPosition) override;
|
|
|
|
void clickPressed(const Point & cursorPosition) override;
|
2023-07-07 00:08:29 +02:00
|
|
|
void hover (bool on) override; //call-in
|
2023-07-06 00:20:44 +02:00
|
|
|
void gesture(bool on, const Point & initialPosition, const Point & finalPosition) override;
|
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
void update();
|
2023-07-07 00:08:29 +02:00
|
|
|
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, EGarrisonType Upg, const CStackInstance * creature_);
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2021-11-28 14:57:38 +02:00
|
|
|
void splitIntoParts(EGarrisonType type, int amount);
|
|
|
|
bool handleSplittingShortcuts(); /// Returns true when some shortcut is pressed, false otherwise
|
2017-10-26 18:40:09 +02:00
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
friend class CGarrisonInt;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Class which manages slots of upper and lower garrison, splitting of units
|
|
|
|
class CGarrisonInt :public CIntObject
|
|
|
|
{
|
2015-08-25 00:45:46 +02:00
|
|
|
/// Chosen slot. Should be changed only via selectSlot.
|
2018-04-07 13:34:11 +02:00
|
|
|
CGarrisonSlot * highlighted;
|
2014-07-13 16:11:25 +03:00
|
|
|
bool inSplittingMode;
|
2018-04-07 13:34:11 +02:00
|
|
|
std::vector<std::shared_ptr<CGarrisonSlot>> availableSlots; ///< Slots of upper and lower garrison
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2018-04-07 13:34:11 +02:00
|
|
|
void createSlots();
|
2021-11-28 14:57:38 +02:00
|
|
|
bool checkSelected(const CGarrisonSlot * selected, TQuantity min = 0) const;
|
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
std::map<EGarrisonType, const CArmedInstance*> armedObjs;
|
|
|
|
|
2014-07-13 16:11:25 +03:00
|
|
|
public:
|
2023-07-16 15:56:42 +02:00
|
|
|
enum class ESlotsLayout
|
2023-07-15 23:11:21 +02:00
|
|
|
{
|
|
|
|
ONE_ROW,
|
|
|
|
TWO_ROWS,
|
|
|
|
REVERSED_TWO_ROWS
|
|
|
|
};
|
|
|
|
|
2015-08-25 00:45:46 +02:00
|
|
|
int interx; ///< Space between slots
|
|
|
|
Point garOffset; ///< Offset between garrisons (not used if only one hero)
|
2018-04-07 13:34:11 +02:00
|
|
|
std::vector<std::shared_ptr<CButton>> splitButtons; ///< May be empty if no buttons
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2023-07-06 00:20:44 +02:00
|
|
|
bool smallIcons; ///< true - 32x32 imgs, false - 58x64
|
|
|
|
bool removableUnits; ///< player Can remove units from up
|
2014-07-13 16:11:25 +03:00
|
|
|
|
2023-07-16 15:56:42 +02:00
|
|
|
ESlotsLayout layout;
|
2023-07-15 23:11:21 +02:00
|
|
|
|
2018-04-07 13:34:11 +02:00
|
|
|
void selectSlot(CGarrisonSlot * slot); ///< @param slot null = deselect
|
2021-11-28 14:57:38 +02:00
|
|
|
const CGarrisonSlot * getSelection() const;
|
2018-04-07 13:34:11 +02:00
|
|
|
|
|
|
|
void setSplittingMode(bool on);
|
|
|
|
bool getSplittingMode();
|
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
bool hasEmptySlot(EGarrisonType type) const;
|
|
|
|
SlotID getEmptySlot(EGarrisonType type) const;
|
2017-03-18 15:21:41 +02:00
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
void setArmy(const CArmedInstance * army, EGarrisonType type);
|
2018-04-07 13:34:11 +02:00
|
|
|
void addSplitBtn(std::shared_ptr<CButton> button);
|
2014-07-13 16:11:25 +03:00
|
|
|
|
|
|
|
void recreateSlots();
|
|
|
|
|
2023-07-07 00:08:29 +02:00
|
|
|
const CArmedInstance* upperArmy() const;
|
|
|
|
const CArmedInstance* lowerArmy() const;
|
|
|
|
const CArmedInstance* army(EGarrisonType which) const;
|
|
|
|
bool isArmyOwned(EGarrisonType which) const;
|
|
|
|
|
2015-08-25 00:45:46 +02:00
|
|
|
void splitClick(); ///< handles click on split button
|
2023-07-06 00:20:44 +02:00
|
|
|
void splitStacks(const CGarrisonSlot * from, const CArmedInstance * armyDest, SlotID slotDest, int amount); ///< TODO: comment me
|
2021-11-28 14:57:38 +02:00
|
|
|
void moveStackToAnotherArmy(const CGarrisonSlot * selected);
|
|
|
|
void bulkMoveArmy(const CGarrisonSlot * selected);
|
|
|
|
void bulkMergeStacks(const CGarrisonSlot * selected); // Gather all creatures of selected type to the selected slot from other hero/garrison slots
|
|
|
|
void bulkSplitStack(const CGarrisonSlot * selected); // Used to separate one-creature troops from main stack
|
|
|
|
void bulkSmartSplitStack(const CGarrisonSlot * selected);
|
2015-08-25 00:45:46 +02:00
|
|
|
|
|
|
|
/// Constructor
|
2023-07-07 00:08:29 +02:00
|
|
|
/// @param position Relative position to parent element
|
|
|
|
/// @param slotInterval Distance between slots;
|
|
|
|
/// @param secondGarrisonOffset
|
2015-08-25 00:45:46 +02:00
|
|
|
/// @param s1, s2 Top and bottom armies
|
|
|
|
/// @param _removableUnits You can take units from top
|
|
|
|
/// @param smallImgs Units images size 64x58 or 32x32
|
2023-07-15 23:11:21 +02:00
|
|
|
/// @param _layout - when TWO_ROWS - Display slots in 2 rows (1st row = 4 slots, 2nd = 3 slots), REVERSED_TWO_ROWS = 3 slots in 1st row
|
2023-07-07 00:08:29 +02:00
|
|
|
CGarrisonInt(const Point & position, int slotInterval,
|
|
|
|
const Point & secondGarrisonOffset,
|
|
|
|
const CArmedInstance * upperArmy, const CArmedInstance * lowerArmy = nullptr,
|
2023-07-16 15:56:42 +02:00
|
|
|
bool _removableUnits = true,
|
|
|
|
bool smallImgs = false,
|
|
|
|
ESlotsLayout _layout = ESlotsLayout::ONE_ROW);
|
2014-07-13 16:11:25 +03:00
|
|
|
};
|