mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Creatures trade panel
This commit is contained in:
@@ -44,6 +44,10 @@ CAltar::CAltar(const IMarket * market, const CGHeroInstance * hero)
|
|||||||
|
|
||||||
void CAltar::deselect()
|
void CAltar::deselect()
|
||||||
{
|
{
|
||||||
|
if(hLeft)
|
||||||
|
hLeft->selection->selectSlot(false);
|
||||||
|
if(hRight)
|
||||||
|
hRight->selection->selectSlot(false);
|
||||||
hLeft = hRight = nullptr;
|
hLeft = hRight = nullptr;
|
||||||
deal->block(true);
|
deal->block(true);
|
||||||
}
|
}
|
||||||
@@ -251,35 +255,36 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
|
|||||||
Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CAltar::sacrificeAll, this));
|
Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CAltar::sacrificeAll, this));
|
||||||
|
|
||||||
// Creating slots for hero creatures
|
// Creating slots for hero creatures
|
||||||
for(int slotIdx = 0; slotIdx < GameConstants::ARMY_SIZE; slotIdx++)
|
SCreaturesPanel::slotsData slots;
|
||||||
|
for(auto slotId = SlotID(0); slotId.num < GameConstants::ARMY_SIZE; slotId++)
|
||||||
{
|
{
|
||||||
CreatureID creatureId = CreatureID::NONE;
|
if(const auto & creature = hero->getCreature(slotId))
|
||||||
if(const auto & creature = hero->getCreature(SlotID(slotIdx)))
|
slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId)));
|
||||||
creatureId = creature->getId();
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto heroSlot = std::make_shared<CTradeableItem>(posSlotsHero[slotIdx], EType::CREATURE, creatureId.num, true, slotIdx);
|
|
||||||
heroSlot->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
|
|
||||||
{
|
|
||||||
onSlotClickPressed(altarSlot, items[0], hLeft, hRight);
|
|
||||||
};
|
|
||||||
heroSlot->subtitle = std::to_string(hero->getStackCount(SlotID(slotIdx)));
|
|
||||||
items[1].emplace_back(heroSlot);
|
|
||||||
}
|
}
|
||||||
|
leftTradePanel = std::make_shared<SCreaturesPanel>([this](std::shared_ptr<CTradeableItem> altarSlot) -> void
|
||||||
|
{
|
||||||
|
onSlotClickPressed(altarSlot, rightTradePanel, hLeft, hRight);
|
||||||
|
}, slots);
|
||||||
|
leftTradePanel->moveBy(Point(45, 110));
|
||||||
|
leftTradePanel->updateSlotsCallback = [this]() -> void
|
||||||
|
{
|
||||||
|
for(auto & heroSlot : leftTradePanel->slots)
|
||||||
|
heroSlot->subtitle = std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)));
|
||||||
|
};
|
||||||
|
|
||||||
// Creating slots for creatures on altar
|
// Creating slots for creatures on altar
|
||||||
assert(items[1].size() <= posSlotsAltar.size());
|
for(auto & slot : slots)
|
||||||
for(const auto & heroSlot : items[1])
|
std::get<2>(slot) = 0;
|
||||||
|
rightTradePanel = std::make_shared<SCreaturesPanel>([this](std::shared_ptr<CTradeableItem> altarSlot) -> void
|
||||||
{
|
{
|
||||||
auto altarSlot = std::make_shared<CTradeableItem>(posSlotsAltar[heroSlot->serial], EType::CREATURE_PLACEHOLDER, heroSlot->id, false, heroSlot->serial);
|
onSlotClickPressed(altarSlot, leftTradePanel, hRight, hLeft);
|
||||||
altarSlot->pos.w = heroSlot->pos.w; altarSlot->pos.h = heroSlot->pos.h;
|
}, slots);
|
||||||
altarSlot->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
|
rightTradePanel->moveBy(Point(334, 110));
|
||||||
|
|
||||||
|
leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
|
||||||
{
|
{
|
||||||
onSlotClickPressed(altarSlot, items[1], hRight, hLeft);
|
return this->hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
|
||||||
};
|
};
|
||||||
items[0].emplace_back(altarSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
readExpValues();
|
readExpValues();
|
||||||
calcExpAltarForHero();
|
calcExpAltarForHero();
|
||||||
@@ -289,7 +294,7 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
|
|||||||
void CAltarCreatures::readExpValues()
|
void CAltarCreatures::readExpValues()
|
||||||
{
|
{
|
||||||
int dump;
|
int dump;
|
||||||
for(auto heroSlot : items[1])
|
for(auto heroSlot : leftTradePanel->slots)
|
||||||
{
|
{
|
||||||
if(heroSlot->id >= 0)
|
if(heroSlot->id >= 0)
|
||||||
market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
|
market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
|
||||||
@@ -340,14 +345,13 @@ void CAltarCreatures::updateSubtitlesForSelected()
|
|||||||
rSubtitle->setText("");
|
rSubtitle->setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAltarCreatures::updateGarrison()
|
void CAltarCreatures::updateSlots()
|
||||||
{
|
{
|
||||||
std::set<std::shared_ptr<CTradeableItem>> empty;
|
rightTradePanel->deleteSlots();
|
||||||
getEmptySlots(empty);
|
leftTradePanel->deleteSlots();
|
||||||
removeItems(empty);
|
assert(leftTradePanel->slots.size() == rightTradePanel->slots.size());
|
||||||
readExpValues();
|
readExpValues();
|
||||||
for(auto & heroSlot : items[1])
|
leftTradePanel->updateSlots();
|
||||||
heroSlot->subtitle = std::to_string(hero->getStackCount(SlotID(heroSlot->serial)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAltarCreatures::deselect()
|
void CAltarCreatures::deselect()
|
||||||
@@ -392,17 +396,17 @@ void CAltarCreatures::makeDeal()
|
|||||||
for(int & units : unitsOnAltar)
|
for(int & units : unitsOnAltar)
|
||||||
units = 0;
|
units = 0;
|
||||||
|
|
||||||
for(auto heroSlot : items[0])
|
for(auto heroSlot : rightTradePanel->slots)
|
||||||
{
|
{
|
||||||
heroSlot->setType(CREATURE_PLACEHOLDER);
|
heroSlot->setType(CREATURE_PLACEHOLDER);
|
||||||
heroSlot->subtitle = "";
|
heroSlot->subtitle.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAltarCreatures::sacrificeAll()
|
void CAltarCreatures::sacrificeAll()
|
||||||
{
|
{
|
||||||
std::optional<SlotID> lastSlot;
|
std::optional<SlotID> lastSlot;
|
||||||
for(auto heroSlot : items[1])
|
for(auto heroSlot : leftTradePanel->slots)
|
||||||
{
|
{
|
||||||
auto stackCount = hero->getStackCount(SlotID(heroSlot->serial));
|
auto stackCount = hero->getStackCount(SlotID(heroSlot->serial));
|
||||||
if(stackCount > unitsOnAltar[heroSlot->serial])
|
if(stackCount > unitsOnAltar[heroSlot->serial])
|
||||||
@@ -417,7 +421,7 @@ void CAltarCreatures::sacrificeAll()
|
|||||||
|
|
||||||
if(hRight)
|
if(hRight)
|
||||||
unitsSlider->scrollTo(unitsOnAltar[hRight->serial]);
|
unitsSlider->scrollTo(unitsOnAltar[hRight->serial]);
|
||||||
for(auto altarSlot : items[0])
|
for(auto altarSlot : rightTradePanel->slots)
|
||||||
updateAltarSlot(altarSlot);
|
updateAltarSlot(altarSlot);
|
||||||
updateSubtitlesForSelected();
|
updateSubtitlesForSelected();
|
||||||
|
|
||||||
@@ -443,18 +447,21 @@ void CAltarCreatures::onUnitsSliderMoved(int newVal)
|
|||||||
updateSubtitlesForSelected();
|
updateSubtitlesForSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot,
|
void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, std::shared_ptr<STradePanel> & oppositePanel,
|
||||||
std::vector<std::shared_ptr<CTradeableItem>> & oppositeSlots,
|
|
||||||
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide)
|
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide)
|
||||||
{
|
{
|
||||||
std::shared_ptr<CTradeableItem> oppositeSlot;
|
std::shared_ptr<CTradeableItem> oppositeSlot;
|
||||||
for(const auto & slot : oppositeSlots)
|
for(const auto & slot : oppositePanel->slots)
|
||||||
if(slot->serial == altarSlot->serial)
|
if(slot->serial == altarSlot->serial)
|
||||||
{
|
{
|
||||||
oppositeSlot = slot;
|
oppositeSlot = slot;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(hCurSide)
|
||||||
|
hCurSide->selection->selectSlot(false);
|
||||||
|
if(hOppSide)
|
||||||
|
hOppSide->selection->selectSlot(false);
|
||||||
if(hCurSide != altarSlot && oppositeSlot)
|
if(hCurSide != altarSlot && oppositeSlot)
|
||||||
{
|
{
|
||||||
hCurSide = altarSlot;
|
hCurSide = altarSlot;
|
||||||
@@ -463,4 +470,7 @@ void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSl
|
|||||||
updateSubtitlesForSelected();
|
updateSubtitlesForSelected();
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
hCurSide->selection->selectSlot(true);
|
||||||
|
hOppSide->selection->selectSlot(true);
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,7 @@ class CAltarCreatures : public CAltar
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
||||||
void updateGarrison();
|
void updateSlots();
|
||||||
void deselect() override;
|
void deselect() override;
|
||||||
TExpType calcExpAltarForHero() override;
|
TExpType calcExpAltarForHero() override;
|
||||||
void makeDeal() override;
|
void makeDeal() override;
|
||||||
@@ -80,24 +80,10 @@ private:
|
|||||||
std::vector<int> expPerUnit;
|
std::vector<int> expPerUnit;
|
||||||
std::shared_ptr<CLabel> lSubtitle, rSubtitle;
|
std::shared_ptr<CLabel> lSubtitle, rSubtitle;
|
||||||
|
|
||||||
const std::vector<Point> posSlotsAltar =
|
|
||||||
{
|
|
||||||
Point(334, 110), Point(417, 110), Point(500, 110),
|
|
||||||
Point(334, 208), Point(417, 208), Point(500, 208),
|
|
||||||
Point(417, 306)
|
|
||||||
};
|
|
||||||
const std::vector<Point> posSlotsHero =
|
|
||||||
{
|
|
||||||
Point(45, 110), Point(128, 110), Point(211, 110),
|
|
||||||
Point(45, 208), Point(128, 208), Point(211, 208),
|
|
||||||
Point(128, 306)
|
|
||||||
};
|
|
||||||
|
|
||||||
void readExpValues();
|
void readExpValues();
|
||||||
void updateControls();
|
void updateControls();
|
||||||
void updateSubtitlesForSelected();
|
void updateSubtitlesForSelected();
|
||||||
void onUnitsSliderMoved(int newVal);
|
void onUnitsSliderMoved(int newVal);
|
||||||
void onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot,
|
void onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, std::shared_ptr<STradePanel> & oppositePanel,
|
||||||
std::vector<std::shared_ptr<CTradeableItem>> & oppositeSlots,
|
|
||||||
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide);
|
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide);
|
||||||
};
|
};
|
||||||
|
@@ -280,44 +280,51 @@ void STradePanel::clearSubtitles()
|
|||||||
slot->subtitle.clear();
|
slot->subtitle.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void STradePanel::updateOffer(int slotIdx, int cost, int qty)
|
void STradePanel::updateOffer(CTradeableItem & slot, int cost, int qty)
|
||||||
{
|
{
|
||||||
slots[slotIdx]->subtitle = std::to_string(qty);
|
slot.subtitle = std::to_string(qty);
|
||||||
if(cost != 1)
|
if(cost != 1)
|
||||||
slots[slotIdx]->subtitle += "/" + std::to_string(cost);
|
slot.subtitle += "/" + std::to_string(cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles)
|
void STradePanel::deleteSlots()
|
||||||
|
{
|
||||||
|
if(deleteSlotsCheck)
|
||||||
|
slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles)
|
||||||
{
|
{
|
||||||
assert(resourcesForTrade.size() == slotsPos.size());
|
assert(resourcesForTrade.size() == slotsPos.size());
|
||||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||||
|
|
||||||
for(const auto & res : resourcesForTrade)
|
for(const auto & res : resourcesForTrade)
|
||||||
{
|
{
|
||||||
slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num));
|
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num));
|
||||||
slots.back()->clickPressedCallback = clickPressedCallback;
|
slot->clickPressedCallback = clickPressedCallback;
|
||||||
slots.back()->pos.w = 69; slots.back()->pos.h = 66;
|
slot->pos.w = 69; slots.back()->pos.h = 66;
|
||||||
slots.back()->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[res.num], slots.back()->pos.dimensions()),
|
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[res.num], slots.back()->pos.dimensions()), Point(1, 1), selectionWidth);
|
||||||
Point(1, 1), selectionWidth);
|
|
||||||
}
|
}
|
||||||
updateSlotsCallback = updateSubtitles;
|
updateSlotsCallback = updateSubtitles;
|
||||||
}
|
}
|
||||||
|
|
||||||
SArtifactsPanel::SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles,
|
SArtifactsPanel::SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||||
std::vector<TradeItemBuy> & arts)
|
std::vector<TradeItemBuy> & arts)
|
||||||
{
|
{
|
||||||
assert(artifactsForTrade == slotsPos.size());
|
assert(slotsForTrade == slotsPos.size());
|
||||||
assert(artifactsForTrade == arts.size());
|
assert(slotsForTrade == arts.size());
|
||||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||||
|
|
||||||
slots.resize(artifactsForTrade);
|
for(auto slotIdx = 0; slotIdx < slotsForTrade; slotIdx++)
|
||||||
int slotNum = 0;
|
|
||||||
for(auto & slot : slots)
|
|
||||||
{
|
{
|
||||||
slot = std::make_shared<CTradeableItem>(slotsPos[slotNum], EType::ARTIFACT_TYPE, arts[slotNum].getNum(), false, slotNum);
|
auto artType = arts[slotIdx].getNum();
|
||||||
|
if(artType != ArtifactID::NONE)
|
||||||
|
{
|
||||||
|
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[slotIdx], EType::ARTIFACT_TYPE, artType, false, slotIdx));
|
||||||
slot->clickPressedCallback = clickPressedCallback;
|
slot->clickPressedCallback = clickPressedCallback;
|
||||||
slot->pos.w = 69; slot->pos.h = 66;
|
slot->pos.w = 69; slot->pos.h = 66;
|
||||||
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotNum++], slot->pos.dimensions()), Point(1, 1), selectionWidth);
|
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotIdx], slot->pos.dimensions()), Point(1, 1), selectionWidth);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateSlotsCallback = updateSubtitles;
|
updateSlotsCallback = updateSubtitles;
|
||||||
}
|
}
|
||||||
@@ -345,6 +352,26 @@ SPlayersPanel::SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCreaturesPanel::SCreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, slotsData & initialSlots)
|
||||||
|
{
|
||||||
|
assert(initialSlots.size() <= GameConstants::ARMY_SIZE);
|
||||||
|
assert(slotsPos.size() <= GameConstants::ARMY_SIZE);
|
||||||
|
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||||
|
|
||||||
|
for(const auto & slotData : initialSlots)
|
||||||
|
{
|
||||||
|
auto slotId = std::get<1>(slotData);
|
||||||
|
auto creaturesNum = std::get<2>(slotData);
|
||||||
|
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[slotId.num],
|
||||||
|
creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, std::get<0>(slotData).num, true, slotId));
|
||||||
|
slot->clickPressedCallback = clickPressedCallback;
|
||||||
|
if(creaturesNum != 0)
|
||||||
|
slot->subtitle = std::to_string(std::get<2>(slotData));
|
||||||
|
slot->pos.w = 58; slots.back()->pos.h = 64;
|
||||||
|
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotId.num], slots.back()->pos.dimensions()), Point(1, 1), selectionWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
|
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
|
||||||
: market(market)
|
: market(market)
|
||||||
, hero(hero)
|
, hero(hero)
|
||||||
@@ -359,7 +386,7 @@ void CTradeBase::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & t
|
|||||||
|
|
||||||
void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
|
void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
|
||||||
{
|
{
|
||||||
items[item->left] -= item;
|
rightTradePanel->slots.erase(std::remove(rightTradePanel->slots.begin(), rightTradePanel->slots.end(), item));
|
||||||
|
|
||||||
if(hRight == item)
|
if(hRight == item)
|
||||||
hRight.reset();
|
hRight.reset();
|
||||||
@@ -367,7 +394,7 @@ void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
|
|||||||
|
|
||||||
void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
|
void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
|
||||||
{
|
{
|
||||||
for(auto item : items[1])
|
for(auto item : leftTradePanel->slots)
|
||||||
if(!hero->getStackCount(SlotID(item->serial)))
|
if(!hero->getStackCount(SlotID(item->serial)))
|
||||||
toRemove.insert(item);
|
toRemove.insert(item);
|
||||||
}
|
}
|
||||||
|
@@ -67,17 +67,20 @@ public:
|
|||||||
|
|
||||||
struct STradePanel : public CIntObject
|
struct STradePanel : public CIntObject
|
||||||
{
|
{
|
||||||
using updateSlotsFunctor = std::function<void()>;
|
using UpdateSlotsFunctor = std::function<void()>;
|
||||||
|
using DeleteSlotsCheck = std::function<bool(std::shared_ptr<CTradeableItem> & slot)>;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<CTradeableItem>> slots;
|
std::vector<std::shared_ptr<CTradeableItem>> slots;
|
||||||
std::function<void()> updateSlotsCallback;
|
UpdateSlotsFunctor updateSlotsCallback;
|
||||||
|
DeleteSlotsCheck deleteSlotsCheck;
|
||||||
std::shared_ptr<CTradeableItem> selected;
|
std::shared_ptr<CTradeableItem> selected;
|
||||||
const int selectionWidth = 2;
|
const int selectionWidth = 2;
|
||||||
|
|
||||||
virtual void updateSlots();
|
virtual void updateSlots();
|
||||||
virtual void deselect();
|
virtual void deselect();
|
||||||
virtual void clearSubtitles();
|
virtual void clearSubtitles();
|
||||||
void updateOffer(int slotIdx, int, int);
|
void updateOffer(CTradeableItem & slot, int, int);
|
||||||
|
void deleteSlots();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SResourcesPanel : public STradePanel
|
struct SResourcesPanel : public STradePanel
|
||||||
@@ -95,7 +98,7 @@ struct SResourcesPanel : public STradePanel
|
|||||||
Point(83, 158)
|
Point(83, 158)
|
||||||
};
|
};
|
||||||
|
|
||||||
SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles);
|
SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SArtifactsPanel : public STradePanel
|
struct SArtifactsPanel : public STradePanel
|
||||||
@@ -106,9 +109,9 @@ struct SArtifactsPanel : public STradePanel
|
|||||||
Point(0, 79), Point(83, 79), Point(166, 79),
|
Point(0, 79), Point(83, 79), Point(166, 79),
|
||||||
Point(83, 158)
|
Point(83, 158)
|
||||||
};
|
};
|
||||||
const size_t artifactsForTrade = 7;
|
const size_t slotsForTrade = 7;
|
||||||
|
|
||||||
SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles,
|
SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||||
std::vector<TradeItemBuy> & arts);
|
std::vector<TradeItemBuy> & arts);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,6 +126,19 @@ struct SPlayersPanel : public STradePanel
|
|||||||
SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback);
|
SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SCreaturesPanel : public STradePanel
|
||||||
|
{
|
||||||
|
using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>;
|
||||||
|
|
||||||
|
const std::vector<Point> slotsPos =
|
||||||
|
{
|
||||||
|
Point(0, 0), Point(83, 0), Point(166, 0),
|
||||||
|
Point(0, 98), Point(83, 98), Point(166, 98),
|
||||||
|
Point(83, 196)
|
||||||
|
};
|
||||||
|
SCreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, slotsData & initialSlots);
|
||||||
|
};
|
||||||
|
|
||||||
class CTradeBase
|
class CTradeBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -48,7 +48,7 @@ void CAltarWindow::updateExpToLevel()
|
|||||||
void CAltarWindow::updateGarrisons()
|
void CAltarWindow::updateGarrisons()
|
||||||
{
|
{
|
||||||
if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar))
|
if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar))
|
||||||
altarCreatures->updateGarrison();
|
altarCreatures->updateSlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAltarWindow::holdsGarrison(const CArmedInstance * army)
|
bool CAltarWindow::holdsGarrison(const CArmedInstance * army)
|
||||||
@@ -130,12 +130,10 @@ void CAltarWindow::showAll(Canvas & to)
|
|||||||
|
|
||||||
if(altar->hRight)
|
if(altar->hRight)
|
||||||
{
|
{
|
||||||
to.drawBorder(Rect::createAround(altar->hRight->pos, 1), Colors::BRIGHT_YELLOW, 2);
|
|
||||||
altar->hRight->showAllAt(altar->pos.topLeft() + Point(396, 423), "", to);
|
altar->hRight->showAllAt(altar->pos.topLeft() + Point(396, 423), "", to);
|
||||||
}
|
}
|
||||||
if(altar->hLeft)
|
if(altar->hLeft)
|
||||||
{
|
{
|
||||||
to.drawBorder(Rect::createAround(altar->hLeft->pos, 1), Colors::BRIGHT_YELLOW, 2);
|
|
||||||
altar->hLeft->showAllAt(altar->pos.topLeft() + Point(150, 423), "", to);
|
altar->hLeft->showAllAt(altar->pos.topLeft() + Point(150, 423), "", to);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -92,7 +92,7 @@ void CTradeWindow::initItems(bool Left)
|
|||||||
int h1, h2; //hlp variables for getting offer
|
int h1, h2; //hlp variables for getting offer
|
||||||
market->getOffer(hLeft->id, slot->id, h1, h2, mode);
|
market->getOffer(hLeft->id, slot->id, h1, h2, mode);
|
||||||
|
|
||||||
rightTradePanel->updateOffer(slot->serial, h1, h2);
|
rightTradePanel->updateOffer(*slot, h1, h2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rightTradePanel->clearSubtitles();
|
rightTradePanel->clearSubtitles();
|
||||||
@@ -111,7 +111,22 @@ void CTradeWindow::initItems(bool Left)
|
|||||||
selectionChanged(left);
|
selectionChanged(left);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
|
if(Left && mode == EMarketMode::CREATURE_RESOURCE)
|
||||||
|
{
|
||||||
|
SCreaturesPanel::slotsData slots;
|
||||||
|
for(auto slotId = SlotID(0); slotId.num < GameConstants::ARMY_SIZE; slotId++)
|
||||||
|
{
|
||||||
|
if(const auto & creature = hero->getCreature(slotId))
|
||||||
|
slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId)));
|
||||||
|
}
|
||||||
|
leftTradePanel = std::make_shared<SCreaturesPanel>(std::bind(clickPressedTradePanel, _1, true), slots);
|
||||||
|
leftTradePanel->moveBy(Point(45, 123));
|
||||||
|
leftTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
|
||||||
|
{
|
||||||
|
return this->hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
|
||||||
{
|
{
|
||||||
leftTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, true),
|
leftTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, true),
|
||||||
[this]() -> void
|
[this]() -> void
|
||||||
@@ -121,9 +136,8 @@ void CTradeWindow::initItems(bool Left)
|
|||||||
});
|
});
|
||||||
leftTradePanel->moveBy(Point(39, 182));
|
leftTradePanel->moveBy(Point(39, 182));
|
||||||
leftTradePanel->updateSlots();
|
leftTradePanel->updateSlots();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(!Left && mode == EMarketMode::RESOURCE_RESOURCE)
|
else if(!Left && mode == EMarketMode::RESOURCE_RESOURCE)
|
||||||
{
|
{
|
||||||
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
|
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
|
||||||
[this, updRightSub]() -> void
|
[this, updRightSub]() -> void
|
||||||
@@ -133,153 +147,28 @@ void CTradeWindow::initItems(bool Left)
|
|||||||
rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
|
rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
|
||||||
});
|
});
|
||||||
rightTradePanel->moveBy(Point(327, 181));
|
rightTradePanel->moveBy(Point(327, 181));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::CREATURE_RESOURCE))
|
else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::CREATURE_RESOURCE))
|
||||||
{
|
{
|
||||||
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
|
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
|
||||||
std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
|
std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
|
||||||
rightTradePanel->moveBy(Point(327, 181));
|
rightTradePanel->moveBy(Point(327, 181));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
|
else if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||||
{
|
{
|
||||||
rightTradePanel = std::make_shared<SArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
|
rightTradePanel = std::make_shared<SArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
|
||||||
std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
|
std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
|
||||||
rightTradePanel->moveBy(Point(327, 181));
|
rightTradePanel->moveBy(Point(327, 181));
|
||||||
return;
|
rightTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
|
||||||
|
{
|
||||||
|
return vstd::contains(market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if(!Left && mode == EMarketMode::RESOURCE_PLAYER)
|
else if(!Left && mode == EMarketMode::RESOURCE_PLAYER)
|
||||||
{
|
{
|
||||||
rightTradePanel = std::make_shared<SPlayersPanel>(std::bind(clickPressedTradePanel, _1, false));
|
rightTradePanel = std::make_shared<SPlayersPanel>(std::bind(clickPressedTradePanel, _1, false));
|
||||||
rightTradePanel->moveBy(Point(333, 83));
|
rightTradePanel->moveBy(Point(333, 83));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> *ids = getItemsIds(Left);
|
|
||||||
std::vector<Rect> pos;
|
|
||||||
int amount = -1;
|
|
||||||
|
|
||||||
getPositionsFor(pos, Left, itemsType[Left]);
|
|
||||||
|
|
||||||
if(Left || !ids)
|
|
||||||
amount = 7;
|
|
||||||
else
|
|
||||||
amount = static_cast<int>(ids->size());
|
|
||||||
|
|
||||||
if(ids)
|
|
||||||
vstd::amin(amount, ids->size());
|
|
||||||
|
|
||||||
for(int j=0; j<amount; j++)
|
|
||||||
{
|
|
||||||
int id = (ids && ids->size()>j) ? (*ids)[j] : j;
|
|
||||||
if(id < 0 && mode != EMarketMode::ARTIFACT_EXP) //when sacrificing artifacts we need to prepare empty slots
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto item = std::make_shared<CTradeableItem>(pos[j].topLeft(), itemsType[Left], id, Left, j);
|
|
||||||
item->pos = pos[j] + this->pos.topLeft();
|
|
||||||
if(mode != EMarketMode::ARTIFACT_EXP)
|
|
||||||
item->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
|
|
||||||
{
|
|
||||||
if(altarSlot->left)
|
|
||||||
{
|
|
||||||
if(hLeft != altarSlot)
|
|
||||||
hLeft = altarSlot;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(hRight != altarSlot)
|
|
||||||
hRight = altarSlot;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selectionChanged(altarSlot->left);
|
|
||||||
};
|
|
||||||
|
|
||||||
items[Left].push_back(item);
|
|
||||||
}
|
|
||||||
vstd::clear_pointer(ids);
|
|
||||||
initSubs(Left);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> *CTradeWindow::getItemsIds(bool Left)
|
|
||||||
{
|
|
||||||
std::vector<int> *ids = nullptr;
|
|
||||||
|
|
||||||
if(Left)
|
|
||||||
{
|
|
||||||
switch(itemsType[1])
|
|
||||||
{
|
|
||||||
case CREATURE:
|
|
||||||
ids = new std::vector<int>;
|
|
||||||
for(int i = 0; i < 7; i++)
|
|
||||||
{
|
|
||||||
if(const CCreature *c = hero->getCreature(SlotID(i)))
|
|
||||||
ids->push_back(c->getId());
|
|
||||||
else
|
|
||||||
ids->push_back(-1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(itemsType[0])
|
|
||||||
{
|
|
||||||
case PLAYER:
|
|
||||||
ids = new std::vector<int>;
|
|
||||||
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
|
|
||||||
if(PlayerColor(i) != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
|
|
||||||
ids->push_back(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const
|
|
||||||
{
|
|
||||||
//seven boxes:
|
|
||||||
// X X X
|
|
||||||
// X X X
|
|
||||||
// X
|
|
||||||
int h = 0, w = 0, x = 0, y = 0, dx = 0, dy = 0;
|
|
||||||
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case CREATURE://45,123
|
|
||||||
x = 45;
|
|
||||||
y = 123;
|
|
||||||
w = 58;
|
|
||||||
h = 64;
|
|
||||||
dx = 83;
|
|
||||||
dy = 98;
|
|
||||||
assert(Left);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int leftToRightOffset = 289;
|
|
||||||
|
|
||||||
const std::vector<Rect> tmp =
|
|
||||||
{
|
|
||||||
Rect(Point(x + 0 * dx, y + 0 * dx), Point(w, h) ),
|
|
||||||
Rect(Point(x + 1 * dx, y + 0 * dx), Point(w, h) ),
|
|
||||||
Rect(Point(x + 2 * dx, y + 0 * dx), Point(w, h) ),
|
|
||||||
Rect(Point(x + 0 * dx, y + 1 * dy), Point(w, h) ),
|
|
||||||
Rect(Point(x + 1 * dx, y + 1 * dy), Point(w, h) ),
|
|
||||||
Rect(Point(x + 2 * dx, y + 1 * dy), Point(w, h) ),
|
|
||||||
Rect(Point(x + 1 * dx, y + 2 * dy), Point(w, h) )
|
|
||||||
};
|
|
||||||
|
|
||||||
vstd::concatenate(poss, tmp);
|
|
||||||
|
|
||||||
if(!Left)
|
|
||||||
{
|
|
||||||
for(Rect &r : poss)
|
|
||||||
r.x += leftToRightOffset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,19 +182,6 @@ void CTradeWindow::initSubs(bool Left)
|
|||||||
rightTradePanel->updateSlots();
|
rightTradePanel->updateSlots();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto item : items[Left])
|
|
||||||
{
|
|
||||||
if(Left)
|
|
||||||
{
|
|
||||||
switch(itemsType[1])
|
|
||||||
{
|
|
||||||
case CREATURE:
|
|
||||||
item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTradeWindow::showAll(Canvas & to)
|
void CTradeWindow::showAll(Canvas & to)
|
||||||
@@ -660,10 +536,8 @@ void CMarketplaceWindow::updateGarrison()
|
|||||||
if(mode != EMarketMode::CREATURE_RESOURCE)
|
if(mode != EMarketMode::CREATURE_RESOURCE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::set<std::shared_ptr<CTradeableItem>> toRemove;
|
leftTradePanel->deleteSlots();
|
||||||
getEmptySlots(toRemove);
|
leftTradePanel->updateSlots();
|
||||||
removeItems(toRemove);
|
|
||||||
initSubs(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMarketplaceWindow::artifactsChanged(bool Left)
|
void CMarketplaceWindow::artifactsChanged(bool Left)
|
||||||
@@ -672,16 +546,7 @@ void CMarketplaceWindow::artifactsChanged(bool Left)
|
|||||||
if(mode != EMarketMode::RESOURCE_ARTIFACT)
|
if(mode != EMarketMode::RESOURCE_ARTIFACT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::vector<TradeItemBuy> available = market->availableItemsIds(mode);
|
rightTradePanel->deleteSlots();
|
||||||
std::set<std::shared_ptr<CTradeableItem>> toRemove;
|
|
||||||
for(auto item : items[0])
|
|
||||||
if(!vstd::contains(available, ArtifactID(item->id)))
|
|
||||||
toRemove.insert(item);
|
|
||||||
|
|
||||||
removeItems(toRemove);
|
|
||||||
|
|
||||||
// clear set to erase final instance of shared_ptr - we want to redraw screen only after it has been deleted
|
|
||||||
toRemove.clear();
|
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -36,8 +36,6 @@ public:
|
|||||||
void initSubs(bool Left);
|
void initSubs(bool Left);
|
||||||
void initTypes();
|
void initTypes();
|
||||||
void initItems(bool Left);
|
void initItems(bool Left);
|
||||||
std::vector<int> *getItemsIds(bool Left); //nullptr if default
|
|
||||||
void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const;
|
|
||||||
void setMode(EMarketMode Mode); //mode setter
|
void setMode(EMarketMode Mode); //mode setter
|
||||||
|
|
||||||
void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot
|
void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot
|
||||||
|
Reference in New Issue
Block a user