mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Merge pull request #3669 from SoundSSGood/market-window-unified
Market window and widgets
This commit is contained in:
commit
f73243eb1c
@ -126,21 +126,25 @@ set(client_SRCS
|
||||
widgets/RadialMenu.cpp
|
||||
widgets/markets/CAltarArtifacts.cpp
|
||||
widgets/markets/CAltarCreatures.cpp
|
||||
widgets/markets/CTradeBase.cpp
|
||||
widgets/markets/CArtifactsBuying.cpp
|
||||
widgets/markets/CArtifactsSelling.cpp
|
||||
widgets/markets/CFreelancerGuild.cpp
|
||||
widgets/markets/CMarketResources.cpp
|
||||
widgets/markets/CTransferResources.cpp
|
||||
widgets/markets/CMarketBase.cpp
|
||||
widgets/markets/TradePanels.cpp
|
||||
|
||||
windows/CAltarWindow.cpp
|
||||
windows/CCastleInterface.cpp
|
||||
windows/CCreatureWindow.cpp
|
||||
windows/CHeroOverview.cpp
|
||||
windows/CHeroWindow.cpp
|
||||
windows/CKingdomInterface.cpp
|
||||
windows/CMapOverview.cpp
|
||||
windows/CMarketWindow.cpp
|
||||
windows/CMessage.cpp
|
||||
windows/CPuzzleWindow.cpp
|
||||
windows/CQuestLog.cpp
|
||||
windows/CSpellWindow.cpp
|
||||
windows/CTradeWindow.cpp
|
||||
windows/CTutorialWindow.cpp
|
||||
windows/CWindowObject.cpp
|
||||
windows/CreaturePurchaseCard.cpp
|
||||
@ -312,10 +316,14 @@ set(client_HEADERS
|
||||
widgets/RadialMenu.h
|
||||
widgets/markets/CAltarArtifacts.h
|
||||
widgets/markets/CAltarCreatures.h
|
||||
widgets/markets/CTradeBase.h
|
||||
widgets/markets/CArtifactsBuying.h
|
||||
widgets/markets/CArtifactsSelling.h
|
||||
widgets/markets/CFreelancerGuild.h
|
||||
widgets/markets/CMarketResources.h
|
||||
widgets/markets/CTransferResources.h
|
||||
widgets/markets/CMarketBase.h
|
||||
widgets/markets/TradePanels.h
|
||||
|
||||
windows/CAltarWindow.h
|
||||
windows/CCastleInterface.h
|
||||
windows/CCreatureWindow.h
|
||||
windows/CHeroOverview.h
|
||||
@ -323,10 +331,10 @@ set(client_HEADERS
|
||||
windows/CKingdomInterface.h
|
||||
windows/CMessage.h
|
||||
windows/CMapOverview.h
|
||||
windows/CMarketWindow.h
|
||||
windows/CPuzzleWindow.h
|
||||
windows/CQuestLog.h
|
||||
windows/CSpellWindow.h
|
||||
windows/CTradeWindow.h
|
||||
windows/CTutorialWindow.h
|
||||
windows/CWindowObject.h
|
||||
windows/CreaturePurchaseCard.h
|
||||
|
@ -49,15 +49,14 @@
|
||||
#include "widgets/CComponent.h"
|
||||
#include "widgets/CGarrisonInt.h"
|
||||
|
||||
#include "windows/CAltarWindow.h"
|
||||
#include "windows/CCastleInterface.h"
|
||||
#include "windows/CCreatureWindow.h"
|
||||
#include "windows/CHeroWindow.h"
|
||||
#include "windows/CKingdomInterface.h"
|
||||
#include "windows/CMarketWindow.h"
|
||||
#include "windows/CPuzzleWindow.h"
|
||||
#include "windows/CQuestLog.h"
|
||||
#include "windows/CSpellWindow.h"
|
||||
#include "windows/CTradeWindow.h"
|
||||
#include "windows/CTutorialWindow.h"
|
||||
#include "windows/GUIClasses.h"
|
||||
#include "windows/InfoWindows.h"
|
||||
@ -425,8 +424,8 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, Prim
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
if (which == PrimarySkill::EXPERIENCE)
|
||||
{
|
||||
for (auto ctw : GH.windows().findWindows<CAltarWindow>())
|
||||
ctw->updateExpToLevel();
|
||||
for(auto ctw : GH.windows().findWindows<CMarketWindow>())
|
||||
ctw->updateHero();
|
||||
}
|
||||
else
|
||||
adventureInt->onHeroChanged(hero);
|
||||
@ -455,8 +454,8 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
|
||||
void CPlayerInterface::receivedResource()
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
for (auto mw : GH.windows().findWindows<CMarketplaceWindow>())
|
||||
mw->resourceChanged();
|
||||
for (auto mw : GH.windows().findWindows<CMarketWindow>())
|
||||
mw->updateResource();
|
||||
|
||||
GH.windows().totalRedraw();
|
||||
}
|
||||
@ -1674,13 +1673,13 @@ void CPlayerInterface::showMarketWindow(const IMarket *market, const CGHeroInsta
|
||||
};
|
||||
|
||||
if(market->allowsTrade(EMarketMode::ARTIFACT_EXP) && visitor->getAlignment() != EAlignment::EVIL)
|
||||
GH.windows().createAndPushWindow<CAltarWindow>(market, visitor, onWindowClosed, EMarketMode::ARTIFACT_EXP);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::ARTIFACT_EXP);
|
||||
else if(market->allowsTrade(EMarketMode::CREATURE_EXP) && visitor->getAlignment() != EAlignment::GOOD)
|
||||
GH.windows().createAndPushWindow<CAltarWindow>(market, visitor, onWindowClosed, EMarketMode::CREATURE_EXP);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::CREATURE_EXP);
|
||||
else if(market->allowsTrade(EMarketMode::CREATURE_UNDEAD))
|
||||
GH.windows().createAndPushWindow<CTransformerWindow>(market, visitor, onWindowClosed);
|
||||
else if(!market->availableModes().empty())
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(market, visitor, onWindowClosed, market->availableModes().front());
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, market->availableModes().front());
|
||||
}
|
||||
|
||||
void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor, QueryID queryID)
|
||||
@ -1701,8 +1700,8 @@ void CPlayerInterface::showHillFortWindow(const CGObjectInstance *object, const
|
||||
void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket * bm)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
for (auto cmw : GH.windows().findWindows<CMarketplaceWindow>())
|
||||
cmw->artifactsChanged(false);
|
||||
for (auto cmw : GH.windows().findWindows<CMarketWindow>())
|
||||
cmw->updateArtifacts();
|
||||
}
|
||||
|
||||
void CPlayerInterface::showTavernWindow(const CGObjectInstance * object, const CGHeroInstance * visitor, QueryID queryID)
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "../mapView/mapHandler.h"
|
||||
#include "../windows/CKingdomInterface.h"
|
||||
#include "../windows/CSpellWindow.h"
|
||||
#include "../windows/CTradeWindow.h"
|
||||
#include "../windows/CMarketWindow.h"
|
||||
#include "../windows/settings/SettingsMainWindow.h"
|
||||
#include "AdventureMapInterface.h"
|
||||
#include "AdventureOptions.h"
|
||||
@ -342,7 +342,7 @@ void AdventureMapShortcuts::showMarketplace()
|
||||
}
|
||||
|
||||
if(townWithMarket) //if any town has marketplace, open window
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(townWithMarket, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(townWithMarket, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
else //if not - complain
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
|
||||
}
|
||||
|
@ -216,6 +216,12 @@ void CButton::setActOnDown(bool on)
|
||||
actOnDown = on;
|
||||
}
|
||||
|
||||
void CButton::setHelp(const std::pair<std::string, std::string> & help)
|
||||
{
|
||||
hoverTexts[0] = help.first;
|
||||
helpBox = help.second;
|
||||
}
|
||||
|
||||
void CButton::block(bool on)
|
||||
{
|
||||
if(on || getState() == EButtonState::BLOCKED) //dont change button state if unblock requested, but it's not blocked
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
void setHoverable(bool on);
|
||||
void setSoundDisabled(bool on);
|
||||
void setActOnDown(bool on);
|
||||
void setHelp(const std::pair<std::string, std::string> & help);
|
||||
|
||||
/// State modifiers
|
||||
bool isBlocked();
|
||||
|
@ -44,23 +44,21 @@ CArtifactsOfHeroBackpack::CArtifactsOfHeroBackpack()
|
||||
|
||||
void CArtifactsOfHeroBackpack::onSliderMoved(int newVal)
|
||||
{
|
||||
if(backpackListBox)
|
||||
backpackListBox->resize(getActiveSlotRowsNum());
|
||||
backpackPos += newVal;
|
||||
auto slot = ArtifactPosition::BACKPACK_START + backpackPos;
|
||||
for(auto artPlace : backpack)
|
||||
{
|
||||
setSlotData(artPlace, slot);
|
||||
slot = slot + 1;
|
||||
}
|
||||
redraw();
|
||||
updateBackpackSlots();
|
||||
}
|
||||
|
||||
void CArtifactsOfHeroBackpack::updateBackpackSlots()
|
||||
{
|
||||
if(backpackListBox)
|
||||
backpackListBox->resize(getActiveSlotRowsNum());
|
||||
CArtifactsOfHeroBase::updateBackpackSlots();
|
||||
auto slot = ArtifactPosition::BACKPACK_START + backpackPos;
|
||||
for(const auto & artPlace : backpack)
|
||||
{
|
||||
setSlotData(artPlace, slot);
|
||||
slot = slot + 1;
|
||||
}
|
||||
redraw();
|
||||
}
|
||||
|
||||
size_t CArtifactsOfHeroBackpack::getActiveSlotRowsNum()
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
|
||||
CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position, const int selectionWidth)
|
||||
{
|
||||
init(
|
||||
std::bind(&CArtifactsOfHeroBase::clickPrassedArtPlace, this, _1, _2),
|
||||
@ -21,25 +21,7 @@ CArtifactsOfHeroMarket::CArtifactsOfHeroMarket(const Point & position)
|
||||
std::bind(&CArtifactsOfHeroBase::scrollBackpack, this, _1));
|
||||
|
||||
for(const auto & [slot, artPlace] : artWorn)
|
||||
artPlace->setSelectionWidth(2);
|
||||
artPlace->setSelectionWidth(selectionWidth);
|
||||
for(auto artPlace : backpack)
|
||||
artPlace->setSelectionWidth(2);
|
||||
artPlace->setSelectionWidth(selectionWidth);
|
||||
};
|
||||
|
||||
void CArtifactsOfHeroMarket::scrollBackpack(bool left)
|
||||
{
|
||||
CArtifactsOfHeroBase::scrollBackpack(left);
|
||||
|
||||
// We may have highlight on one of backpack artifacts
|
||||
if(selectArtCallback)
|
||||
{
|
||||
for(const auto & artPlace : backpack)
|
||||
{
|
||||
if(artPlace->isSelected())
|
||||
{
|
||||
selectArtCallback(artPlace.get());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -14,8 +14,7 @@
|
||||
class CArtifactsOfHeroMarket : public CArtifactsOfHeroBase
|
||||
{
|
||||
public:
|
||||
std::function<void(CArtPlace*)> selectArtCallback;
|
||||
std::function<void(const CArtPlace*)> selectArtCallback;
|
||||
|
||||
CArtifactsOfHeroMarket(const Point & position);
|
||||
void scrollBackpack(bool left) override;
|
||||
CArtifactsOfHeroMarket(const Point & position, const int selectionWidth);
|
||||
};
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../eventsSDL/InputHandler.h"
|
||||
#include "../windows/CTradeWindow.h"
|
||||
#include "../windows/CMarketWindow.h"
|
||||
#include "../widgets/CGarrisonInt.h"
|
||||
#include "../widgets/GraphicalPrimitiveCanvas.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
@ -474,7 +474,7 @@ void CInteractableTownTooltip::init(const CGTownInstance * town)
|
||||
{
|
||||
if(town->builtBuildings.count(BuildingID::MARKETPLACE))
|
||||
{
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ bool CSlider::receiveEvent(const Point &position, int eventType) const
|
||||
return testTarget.isInside(position);
|
||||
}
|
||||
|
||||
CSlider::CSlider(Point position, int totalw, const std::function<void(int)> & Moved, int Capacity, int Amount, int Value, Orientation orientation, CSlider::EStyle style)
|
||||
CSlider::CSlider(Point position, int totalw, const SliderMovingFunctor & Moved, int Capacity, int Amount, int Value, Orientation orientation, CSlider::EStyle style)
|
||||
: Scrollable(LCLICK | DRAG, position, orientation ),
|
||||
capacity(Capacity),
|
||||
amount(Amount),
|
||||
|
@ -75,13 +75,15 @@ public:
|
||||
void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override;
|
||||
void showAll(Canvas & to) override;
|
||||
|
||||
using SliderMovingFunctor = std::function<void(int)>;
|
||||
|
||||
/// @param position coordinates of slider
|
||||
/// @param length length of slider ribbon, including left/right buttons
|
||||
/// @param Moved function that will be called whenever slider moves
|
||||
/// @param Capacity maximal number of visible at once elements
|
||||
/// @param Amount total amount of elements, including not visible
|
||||
/// @param Value starting position
|
||||
CSlider(Point position, int length, const std::function<void(int)> & Moved, int Capacity, int Amount,
|
||||
CSlider(Point position, int length, const SliderMovingFunctor & Moved, int Capacity, int Amount,
|
||||
int Value, Orientation orientation, EStyle style = BROWN);
|
||||
~CSlider();
|
||||
};
|
||||
|
@ -97,6 +97,19 @@ void CLabel::setText(const std::string & Txt)
|
||||
}
|
||||
}
|
||||
|
||||
void CLabel::clear()
|
||||
{
|
||||
text.clear();
|
||||
|
||||
if(autoRedraw)
|
||||
{
|
||||
if(background || !parent)
|
||||
redraw();
|
||||
else
|
||||
parent->redraw();
|
||||
}
|
||||
}
|
||||
|
||||
void CLabel::setMaxWidth(int width)
|
||||
{
|
||||
maxWidth = width;
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
virtual void setText(const std::string & Txt);
|
||||
virtual void setMaxWidth(int width);
|
||||
virtual void setColor(const ColorRGBA & Color);
|
||||
void clear();
|
||||
size_t getWidth();
|
||||
|
||||
CLabel(int x = 0, int y = 0, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT,
|
||||
|
@ -26,21 +26,19 @@
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
|
||||
CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CTradeBase(market, hero)
|
||||
: CMarketBase(market, hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
assert(market);
|
||||
assert(dynamic_cast<const CGArtifactsAltar*>(market));
|
||||
auto altarObj = dynamic_cast<const CGArtifactsAltar*>(market);
|
||||
altarId = altarObj->id;
|
||||
altarArtifacts = altarObj;
|
||||
|
||||
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"),
|
||||
deal = std::make_shared<CButton>(Point(269, 520), AnimationPath::builtin("ALTSACR.DEF"),
|
||||
CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); });
|
||||
labels.emplace_back(std::make_shared<CLabel>(450, 34, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
|
||||
labels.emplace_back(std::make_shared<CLabel>(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
|
||||
selectedCost = std::make_shared<CLabel>(302, 500, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedArt = std::make_shared<CArtPlace>(Point(280, 442));
|
||||
labels.emplace_back(std::make_shared<CLabel>(450, 32, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
|
||||
labels.emplace_back(std::make_shared<CLabel>(302, 424, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
|
||||
|
||||
sacrificeAllButton = std::make_shared<CButton>(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"),
|
||||
CGI->generaltexth->zelp[571], std::bind(&CExperienceAltar::sacrificeAll, this));
|
||||
@ -50,50 +48,63 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
|
||||
CGI->generaltexth->zelp[570], std::bind(&CAltarArtifacts::sacrificeBackpack, this));
|
||||
sacrificeBackpackButton->block(hero->artifactsInBackpack.empty());
|
||||
|
||||
// Hero's artifacts
|
||||
heroArts = std::make_shared<CArtifactsOfHeroAltar>(Point(-365, -11));
|
||||
heroArts->setHero(hero);
|
||||
|
||||
int slotNum = 0;
|
||||
for(auto & altarSlotPos : posSlotsAltar)
|
||||
{
|
||||
auto altarSlot = std::make_shared<CTradeableItem>(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, false, slotNum);
|
||||
altarSlot->clickPressedCallback = std::bind(&CAltarArtifacts::onSlotClickPressed, this, _1, hRight);
|
||||
altarSlot->subtitle.clear();
|
||||
items.front().emplace_back(altarSlot);
|
||||
slotNum++;
|
||||
}
|
||||
// Altar
|
||||
offerTradePanel = std::make_shared<ArtifactsAltarPanel>([this](const std::shared_ptr<CTradeableItem> & altarSlot)
|
||||
{
|
||||
CAltarArtifacts::onSlotClickPressed(altarSlot, offerTradePanel);
|
||||
});
|
||||
offerTradePanel->updateSlotsCallback = std::bind(&CAltarArtifacts::updateAltarSlots, this);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(315, 52));
|
||||
|
||||
expForHero->setText(std::to_string(0));
|
||||
CTradeBase::deselect();
|
||||
CMarketBase::updateShowcases();
|
||||
CAltarArtifacts::deselect();
|
||||
};
|
||||
|
||||
TExpType CAltarArtifacts::calcExpAltarForHero()
|
||||
{
|
||||
TExpType expOnAltar(0);
|
||||
for(const auto & tradeSlot : tradeSlotsMap)
|
||||
expOnAltar += calcExpCost(tradeSlot.first);
|
||||
expOnAltar += calcExpCost(tradeSlot.second->getTypeId());
|
||||
expForHero->setText(std::to_string(expOnAltar));
|
||||
return expOnAltar;
|
||||
}
|
||||
|
||||
void CAltarArtifacts::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CExperienceAltar::deselect();
|
||||
tradeSlotsMap.clear();
|
||||
// The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately.
|
||||
for(const auto & slot : offerTradePanel->slots)
|
||||
slot->clear();
|
||||
offerTradePanel->showcaseSlot->clear();
|
||||
}
|
||||
|
||||
void CAltarArtifacts::update()
|
||||
{
|
||||
CMarketBase::update();
|
||||
CExperienceAltar::update();
|
||||
if(const auto art = hero->getArt(ArtifactPosition::TRANSITION_POS))
|
||||
offerQty = calcExpCost(art->getTypeId());
|
||||
else
|
||||
offerQty = 0;
|
||||
updateShowcases();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CAltarArtifacts::makeDeal()
|
||||
{
|
||||
std::vector<TradeItemSell> positions;
|
||||
for(const auto & [artInst, altarSlot] : tradeSlotsMap)
|
||||
for(const auto & [altarSlot, artInst] : tradeSlotsMap)
|
||||
{
|
||||
positions.push_back(artInst->getId());
|
||||
}
|
||||
LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_EXP, positions, std::vector<TradeItemBuy>(), std::vector<ui32>(), hero);
|
||||
|
||||
tradeSlotsMap.clear();
|
||||
// The event for removing artifacts from the altar will not be triggered. Therefore, we clean the altar immediately.
|
||||
for(auto item : items[0])
|
||||
{
|
||||
item->setID(-1);
|
||||
item->subtitle.clear();
|
||||
}
|
||||
calcExpAltarForHero();
|
||||
deal->block(tradeSlotsMap.empty());
|
||||
deselect();
|
||||
}
|
||||
|
||||
void CAltarArtifacts::sacrificeAll()
|
||||
@ -106,63 +117,59 @@ void CAltarArtifacts::sacrificeBackpack()
|
||||
LOCPLINT->cb->bulkMoveArtifacts(heroArts->getHero()->id, altarId, false, false, true);
|
||||
}
|
||||
|
||||
void CAltarArtifacts::setSelectedArtifact(const CArtifactInstance * art)
|
||||
{
|
||||
selectedArt->setArtifact(art);
|
||||
selectedCost->setText(art == nullptr ? "" : std::to_string(calcExpCost(art)));
|
||||
}
|
||||
|
||||
std::shared_ptr<CArtifactsOfHeroAltar> CAltarArtifacts::getAOHset() const
|
||||
{
|
||||
return heroArts;
|
||||
}
|
||||
|
||||
ObjectInstanceID CAltarArtifacts::getObjId() const
|
||||
{
|
||||
return altarId;
|
||||
}
|
||||
|
||||
void CAltarArtifacts::updateSlots()
|
||||
void CAltarArtifacts::updateAltarSlots()
|
||||
{
|
||||
assert(altarArtifacts->artifactsInBackpack.size() <= GameConstants::ALTAR_ARTIFACTS_SLOTS);
|
||||
assert(tradeSlotsMap.size() <= GameConstants::ALTAR_ARTIFACTS_SLOTS);
|
||||
|
||||
auto slotsToAdd = tradeSlotsMap;
|
||||
for(auto & altarSlot : items[0])
|
||||
auto tradeSlotsMapNewArts = tradeSlotsMap;
|
||||
for(const auto & altarSlot : offerTradePanel->slots)
|
||||
if(altarSlot->id != -1)
|
||||
{
|
||||
if(tradeSlotsMap.find(altarSlot->getArtInstance()) == tradeSlotsMap.end())
|
||||
if(tradeSlotsMap.find(altarSlot) == tradeSlotsMap.end())
|
||||
{
|
||||
altarSlot->setID(-1);
|
||||
altarSlot->subtitle.clear();
|
||||
altarSlot->subtitle->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
slotsToAdd.erase(altarSlot->getArtInstance());
|
||||
tradeSlotsMapNewArts.erase(altarSlot);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto & tradeSlot : slotsToAdd)
|
||||
for(auto & tradeSlot : tradeSlotsMapNewArts)
|
||||
{
|
||||
assert(tradeSlot.second->id == -1);
|
||||
assert(altarArtifacts->getSlotByInstance(tradeSlot.first) != ArtifactPosition::PRE_FIRST);
|
||||
tradeSlot.second->setArtInstance(tradeSlot.first);
|
||||
tradeSlot.second->subtitle = std::to_string(calcExpCost(tradeSlot.first));
|
||||
assert(tradeSlot.first->id == -1);
|
||||
assert(altarArtifacts->getSlotByInstance(tradeSlot.second) != ArtifactPosition::PRE_FIRST);
|
||||
tradeSlot.first->setID(tradeSlot.second->getTypeId().num);
|
||||
tradeSlot.first->subtitle->setText(std::to_string(calcExpCost(tradeSlot.second->getTypeId())));
|
||||
}
|
||||
for(auto & slotInfo : altarArtifacts->artifactsInBackpack)
|
||||
|
||||
auto newArtsFromBulkMove = altarArtifacts->artifactsInBackpack;
|
||||
for(const auto & [altarSlot, art] : tradeSlotsMap)
|
||||
{
|
||||
if(tradeSlotsMap.find(slotInfo.artifact) == tradeSlotsMap.end())
|
||||
{
|
||||
for(auto & altarSlot : items[0])
|
||||
if(altarSlot->id == -1)
|
||||
{
|
||||
altarSlot->setArtInstance(slotInfo.artifact);
|
||||
altarSlot->subtitle = std::to_string(calcExpCost(slotInfo.artifact));
|
||||
tradeSlotsMap.try_emplace(slotInfo.artifact, altarSlot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
newArtsFromBulkMove.erase(std::remove_if(newArtsFromBulkMove.begin(), newArtsFromBulkMove.end(), [artForRemove = art](auto & slotInfo)
|
||||
{
|
||||
return slotInfo.artifact == artForRemove;
|
||||
}));
|
||||
}
|
||||
for(const auto & slotInfo : newArtsFromBulkMove)
|
||||
{
|
||||
for(const auto & altarSlot : offerTradePanel->slots)
|
||||
if(altarSlot->id == -1)
|
||||
{
|
||||
altarSlot->setID(slotInfo.artifact->getTypeId().num);
|
||||
altarSlot->subtitle->setText(std::to_string(calcExpCost(slotInfo.artifact->getTypeId())));
|
||||
tradeSlotsMap.try_emplace(altarSlot, slotInfo.artifact);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
calcExpAltarForHero();
|
||||
deal->block(tradeSlotsMap.empty());
|
||||
}
|
||||
@ -175,7 +182,18 @@ void CAltarArtifacts::putBackArtifacts()
|
||||
LOCPLINT->cb->bulkMoveArtifacts(altarId, heroArts->getHero()->id, false, true, true);
|
||||
}
|
||||
|
||||
void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
|
||||
CMarketBase::MarketShowcasesParams CAltarArtifacts::getShowcasesParams() const
|
||||
{
|
||||
if(const auto art = hero->getArt(ArtifactPosition::TRANSITION_POS))
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
std::nullopt,
|
||||
ShowcaseParams {std::to_string(offerQty), CGI->artifacts()->getByIndex(art->getTypeId())->getIconIndex()}
|
||||
};
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<TradePanelBase> & curPanel)
|
||||
{
|
||||
assert(altarSlot);
|
||||
|
||||
@ -186,7 +204,7 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
|
||||
if(pickedArtInst->artType->isTradable())
|
||||
{
|
||||
if(altarSlot->id == -1)
|
||||
tradeSlotsMap.try_emplace(pickedArtInst, altarSlot);
|
||||
tradeSlotsMap.try_emplace(altarSlot, pickedArtInst);
|
||||
deal->block(false);
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(heroArts->getHero()->id, ArtifactPosition::TRANSITION_POS),
|
||||
@ -199,19 +217,20 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(const CArtifactInstance * art = altarSlot->getArtInstance())
|
||||
else if(altarSlot->id != -1)
|
||||
{
|
||||
const auto slot = altarArtifacts->getSlotByInstance(art);
|
||||
assert(tradeSlotsMap.at(altarSlot));
|
||||
const auto slot = altarArtifacts->getSlotByInstance(tradeSlotsMap.at(altarSlot));
|
||||
assert(slot != ArtifactPosition::PRE_FIRST);
|
||||
LOCPLINT->cb->swapArtifacts(ArtifactLocation(altarId, slot), ArtifactLocation(hero->id, ArtifactPosition::TRANSITION_POS));
|
||||
tradeSlotsMap.erase(art);
|
||||
tradeSlotsMap.erase(altarSlot);
|
||||
}
|
||||
}
|
||||
|
||||
TExpType CAltarArtifacts::calcExpCost(const CArtifactInstance * art)
|
||||
TExpType CAltarArtifacts::calcExpCost(ArtifactID id) const
|
||||
{
|
||||
int dmp = 0;
|
||||
int bidQty = 0;
|
||||
int expOfArt = 0;
|
||||
market->getOffer(art->getTypeId(), 0, dmp, expOfArt, EMarketMode::ARTIFACT_EXP);
|
||||
market->getOffer(id, 0, bidQty, expOfArt, EMarketMode::ARTIFACT_EXP);
|
||||
return hero->calculateXp(expOfArt);
|
||||
}
|
||||
|
@ -10,43 +10,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "../CArtifactsOfHeroAltar.h"
|
||||
#include "CTradeBase.h"
|
||||
#include "CMarketBase.h"
|
||||
|
||||
class CAltarArtifacts : public CExperienceAltar
|
||||
{
|
||||
public:
|
||||
CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero);
|
||||
TExpType calcExpAltarForHero() override;
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
void update() override;
|
||||
void sacrificeAll() override;
|
||||
void sacrificeBackpack();
|
||||
void setSelectedArtifact(const CArtifactInstance * art);
|
||||
std::shared_ptr<CArtifactsOfHeroAltar> getAOHset() const;
|
||||
ObjectInstanceID getObjId() const;
|
||||
void updateSlots();
|
||||
void putBackArtifacts();
|
||||
|
||||
private:
|
||||
ObjectInstanceID altarId;
|
||||
const CArtifactSet * altarArtifacts;
|
||||
std::shared_ptr<CArtPlace> selectedArt;
|
||||
std::shared_ptr<CLabel> selectedCost;
|
||||
std::shared_ptr<CButton> sacrificeBackpackButton;
|
||||
std::shared_ptr<CArtifactsOfHeroAltar> heroArts;
|
||||
std::map<const CArtifactInstance*, std::shared_ptr<CTradeableItem>> tradeSlotsMap;
|
||||
std::map<std::shared_ptr<CTradeableItem>, const CArtifactInstance*> tradeSlotsMap;
|
||||
|
||||
const std::vector<Point> posSlotsAltar =
|
||||
{
|
||||
Point(317, 53), Point(371, 53), Point(425, 53),
|
||||
Point(479, 53), Point(533, 53), Point(317, 123),
|
||||
Point(371, 123), Point(425, 123), Point(479, 123),
|
||||
Point(533, 123), Point(317, 193), Point(371, 193),
|
||||
Point(425, 193), Point(479, 193), Point(533, 193),
|
||||
Point(317, 263), Point(371, 263), Point(425, 263),
|
||||
Point(479, 263), Point(533, 263), Point(398, 333),
|
||||
Point(452, 333)
|
||||
};
|
||||
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
|
||||
TExpType calcExpCost(const CArtifactInstance * art);
|
||||
void updateAltarSlots();
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & altarSlot, std::shared_ptr<TradePanelBase> & curPanel) override;
|
||||
TExpType calcExpCost(ArtifactID id) const;
|
||||
};
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/Slider.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
@ -24,23 +23,23 @@
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
#include "../../../lib/MetaString.h"
|
||||
|
||||
CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CTradeBase(market, hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CMarketSlider(std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1))
|
||||
, CMarketTraderText(Point(28, 31), FONT_MEDIUM, Colors::YELLOW)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("ALTSACR.DEF"),
|
||||
deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("ALTSACR.DEF"),
|
||||
CGI->generaltexth->zelp[584], [this]() {CAltarCreatures::makeDeal();});
|
||||
labels.emplace_back(std::make_shared<CLabel>(155, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW,
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
|
||||
labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
|
||||
texts.emplace_back(std::make_unique<CTextBox>(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
|
||||
lSubtitle = std::make_shared<CLabel>(180, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
rSubtitle = std::make_shared<CLabel>(426, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
|
||||
offerSlider = std::make_shared<CSlider>(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL);
|
||||
maxUnits = std::make_shared<CButton>(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider));
|
||||
offerSlider->moveTo(pos.topLeft() + Point(231, 481));
|
||||
maxAmount->setHelp(CGI->generaltexth->zelp[578]);
|
||||
|
||||
unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0);
|
||||
expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
|
||||
@ -48,39 +47,46 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
|
||||
Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CExperienceAltar::sacrificeAll, this));
|
||||
|
||||
// Hero creatures panel
|
||||
assert(leftTradePanel);
|
||||
leftTradePanel->moveBy(Point(45, 110));
|
||||
leftTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitle, this);
|
||||
for(const auto & slot : leftTradePanel->slots)
|
||||
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, hLeft);};
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(45, 110));
|
||||
bidTradePanel->showcaseSlot->moveTo(pos.topLeft() + Point(149, 422));
|
||||
bidTradePanel->showcaseSlot->subtitle->moveBy(Point(0, 3));
|
||||
for(const auto & slot : bidTradePanel->slots)
|
||||
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, bidTradePanel);};
|
||||
|
||||
// Altar creatures panel
|
||||
rightTradePanel = std::make_shared<CreaturesPanel>([this](const std::shared_ptr<CTradeableItem> & altarSlot)
|
||||
offerTradePanel = std::make_shared<CreaturesPanel>([this](const std::shared_ptr<CTradeableItem> & altarSlot)
|
||||
{
|
||||
CAltarCreatures::onSlotClickPressed(altarSlot, hRight);
|
||||
}, leftTradePanel->slots);
|
||||
rightTradePanel->moveBy(Point(334, 110));
|
||||
|
||||
leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
|
||||
CAltarCreatures::onSlotClickPressed(altarSlot, offerTradePanel);
|
||||
}, bidTradePanel->slots);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(334, 110));
|
||||
offerTradePanel->showcaseSlot->moveTo(pos.topLeft() + Point(395, 422));
|
||||
offerTradePanel->showcaseSlot->subtitle->moveBy(Point(0, 3));
|
||||
offerTradePanel->updateSlotsCallback = [this]()
|
||||
{
|
||||
for(const auto & altarSlot : offerTradePanel->slots)
|
||||
updateAltarSlot(altarSlot);
|
||||
};
|
||||
bidTradePanel->deleteSlotsCheck = offerTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
|
||||
|
||||
readExpValues();
|
||||
expForHero->setText(std::to_string(0));
|
||||
CAltarCreatures::deselect();
|
||||
};
|
||||
|
||||
void CAltarCreatures::readExpValues()
|
||||
{
|
||||
int dump;
|
||||
for(auto heroSlot : leftTradePanel->slots)
|
||||
int bidQty = 0;
|
||||
for(const auto & heroSlot : bidTradePanel->slots)
|
||||
{
|
||||
if(heroSlot->id >= 0)
|
||||
market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
|
||||
market->getOffer(heroSlot->id, 0, bidQty, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
|
||||
}
|
||||
}
|
||||
|
||||
void CAltarCreatures::updateControls()
|
||||
void CAltarCreatures::highlightingChanged()
|
||||
{
|
||||
int sliderAmount = 0;
|
||||
if(hLeft)
|
||||
if(bidTradePanel->isHighlighted())
|
||||
{
|
||||
std::optional<SlotID> lastSlot;
|
||||
for(auto slot = SlotID(0); slot.num < GameConstants::ARMY_SIZE; slot++)
|
||||
@ -98,44 +104,32 @@ void CAltarCreatures::updateControls()
|
||||
}
|
||||
}
|
||||
}
|
||||
sliderAmount = hero->getStackCount(SlotID(hLeft->serial));
|
||||
if(lastSlot.has_value() && lastSlot.value() == SlotID(hLeft->serial))
|
||||
sliderAmount = hero->getStackCount(SlotID(bidTradePanel->highlightedSlot->serial));
|
||||
if(lastSlot.has_value() && lastSlot.value() == SlotID(bidTradePanel->highlightedSlot->serial))
|
||||
sliderAmount--;
|
||||
}
|
||||
offerSlider->setAmount(sliderAmount);
|
||||
offerSlider->block(!offerSlider->getAmount());
|
||||
if(hLeft)
|
||||
offerSlider->scrollTo(unitsOnAltar[hLeft->serial]);
|
||||
maxUnits->block(offerSlider->getAmount() == 0);
|
||||
if(bidTradePanel->isHighlighted())
|
||||
offerSlider->scrollTo(unitsOnAltar[bidTradePanel->highlightedSlot->serial]);
|
||||
maxAmount->block(offerSlider->getAmount() == 0);
|
||||
updateShowcases();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
void CAltarCreatures::updateSubtitlesForSelected()
|
||||
void CAltarCreatures::update()
|
||||
{
|
||||
if(hLeft)
|
||||
lSubtitle->setText(std::to_string(offerSlider->getValue()));
|
||||
else
|
||||
lSubtitle->setText("");
|
||||
if(hRight)
|
||||
rSubtitle->setText(hRight->subtitle);
|
||||
else
|
||||
rSubtitle->setText("");
|
||||
}
|
||||
|
||||
void CAltarCreatures::updateSlots()
|
||||
{
|
||||
rightTradePanel->deleteSlots();
|
||||
leftTradePanel->deleteSlots();
|
||||
assert(leftTradePanel->slots.size() == rightTradePanel->slots.size());
|
||||
readExpValues();
|
||||
leftTradePanel->updateSlots();
|
||||
CMarketBase::update();
|
||||
CExperienceAltar::update();
|
||||
assert(bidTradePanel->slots.size() == offerTradePanel->slots.size());
|
||||
}
|
||||
|
||||
void CAltarCreatures::deselect()
|
||||
{
|
||||
CTradeBase::deselect();
|
||||
offerSlider->block(true);
|
||||
maxUnits->block(true);
|
||||
updateSubtitlesForSelected();
|
||||
CMarketBase::deselect();
|
||||
CExperienceAltar::deselect();
|
||||
CMarketSlider::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
}
|
||||
|
||||
TExpType CAltarCreatures::calcExpAltarForHero()
|
||||
@ -151,10 +145,6 @@ TExpType CAltarCreatures::calcExpAltarForHero()
|
||||
|
||||
void CAltarCreatures::makeDeal()
|
||||
{
|
||||
deselect();
|
||||
offerSlider->scrollTo(0);
|
||||
expForHero->setText(std::to_string(0));
|
||||
|
||||
std::vector<TradeItemSell> ids;
|
||||
std::vector<ui32> toSacrifice;
|
||||
|
||||
@ -172,17 +162,29 @@ void CAltarCreatures::makeDeal()
|
||||
for(int & units : unitsOnAltar)
|
||||
units = 0;
|
||||
|
||||
for(auto heroSlot : rightTradePanel->slots)
|
||||
for(auto heroSlot : offerTradePanel->slots)
|
||||
{
|
||||
heroSlot->setType(EType::CREATURE_PLACEHOLDER);
|
||||
heroSlot->subtitle.clear();
|
||||
heroSlot->subtitle->clear();
|
||||
}
|
||||
deselect();
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CAltarCreatures::getShowcasesParams() const
|
||||
{
|
||||
std::optional<ShowcaseParams> bidSelected = std::nullopt;
|
||||
std::optional<ShowcaseParams> offerSelected = std::nullopt;
|
||||
if(bidTradePanel->isHighlighted())
|
||||
bidSelected = ShowcaseParams {std::to_string(offerSlider->getValue()), CGI->creatures()->getByIndex(bidTradePanel->getSelectedItemId())->getIconIndex()};
|
||||
if(offerTradePanel->isHighlighted() && offerSlider->getValue() > 0)
|
||||
offerSelected = ShowcaseParams {offerTradePanel->highlightedSlot->subtitle->getText(), CGI->creatures()->getByIndex(offerTradePanel->getSelectedItemId())->getIconIndex()};
|
||||
return MarketShowcasesParams {bidSelected, offerSelected};
|
||||
}
|
||||
|
||||
void CAltarCreatures::sacrificeAll()
|
||||
{
|
||||
std::optional<SlotID> lastSlot;
|
||||
for(auto heroSlot : leftTradePanel->slots)
|
||||
for(auto heroSlot : bidTradePanel->slots)
|
||||
{
|
||||
auto stackCount = hero->getStackCount(SlotID(heroSlot->serial));
|
||||
if(stackCount > unitsOnAltar[heroSlot->serial])
|
||||
@ -192,49 +194,51 @@ void CAltarCreatures::sacrificeAll()
|
||||
unitsOnAltar[heroSlot->serial] = stackCount;
|
||||
}
|
||||
}
|
||||
assert(lastSlot.has_value());
|
||||
unitsOnAltar[lastSlot.value().num]--;
|
||||
if(hero->needsLastStack())
|
||||
{
|
||||
assert(lastSlot.has_value());
|
||||
unitsOnAltar[lastSlot.value().num]--;
|
||||
}
|
||||
|
||||
if(hRight)
|
||||
offerSlider->scrollTo(unitsOnAltar[hRight->serial]);
|
||||
for(auto altarSlot : rightTradePanel->slots)
|
||||
updateAltarSlot(altarSlot);
|
||||
updateSubtitlesForSelected();
|
||||
if(offerTradePanel->isHighlighted())
|
||||
offerSlider->scrollTo(unitsOnAltar[offerTradePanel->highlightedSlot->serial]);
|
||||
offerTradePanel->update();
|
||||
updateShowcases();
|
||||
|
||||
deal->block(calcExpAltarForHero() == 0);
|
||||
}
|
||||
|
||||
void CAltarCreatures::updateAltarSlot(std::shared_ptr<CTradeableItem> slot)
|
||||
void CAltarCreatures::updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot)
|
||||
{
|
||||
auto units = unitsOnAltar[slot->serial];
|
||||
slot->setType(units > 0 ? EType::CREATURE : EType::CREATURE_PLACEHOLDER);
|
||||
slot->subtitle = units > 0 ?
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : "";
|
||||
slot->subtitle->setText(units > 0 ?
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : "");
|
||||
}
|
||||
|
||||
void CAltarCreatures::onOfferSliderMoved(int newVal)
|
||||
{
|
||||
if(hLeft)
|
||||
unitsOnAltar[hLeft->serial] = newVal;
|
||||
if(hRight)
|
||||
updateAltarSlot(hRight);
|
||||
if(bidTradePanel->isHighlighted())
|
||||
unitsOnAltar[bidTradePanel->highlightedSlot->serial] = newVal;
|
||||
if(offerTradePanel->isHighlighted())
|
||||
updateAltarSlot(offerTradePanel->highlightedSlot);
|
||||
deal->block(calcExpAltarForHero() == 0);
|
||||
updateControls();
|
||||
updateSubtitlesForSelected();
|
||||
highlightingChanged();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSide)
|
||||
void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<TradePanelBase> & curPanel)
|
||||
{
|
||||
if(hCurSide == newSlot)
|
||||
assert(newSlot);
|
||||
assert(curPanel);
|
||||
if(newSlot == curPanel->highlightedSlot)
|
||||
return;
|
||||
|
||||
auto * oppositeSlot = &hLeft;
|
||||
auto oppositePanel = leftTradePanel;
|
||||
CTradeBase::onSlotClickPressed(newSlot, hCurSide);
|
||||
if(hCurSide == hLeft)
|
||||
auto oppositePanel = bidTradePanel;
|
||||
curPanel->onSlotClickPressed(newSlot);
|
||||
if(curPanel->highlightedSlot == bidTradePanel->highlightedSlot)
|
||||
{
|
||||
oppositeSlot = &hRight;
|
||||
oppositePanel = rightTradePanel;
|
||||
oppositePanel = offerTradePanel;
|
||||
}
|
||||
std::shared_ptr<CTradeableItem> oppositeNewSlot;
|
||||
for(const auto & slot : oppositePanel->slots)
|
||||
@ -244,8 +248,21 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
|
||||
break;
|
||||
}
|
||||
assert(oppositeNewSlot);
|
||||
CTradeBase::onSlotClickPressed(oppositeNewSlot, *oppositeSlot);
|
||||
updateControls();
|
||||
updateSubtitlesForSelected();
|
||||
oppositePanel->onSlotClickPressed(oppositeNewSlot);
|
||||
highlightingChanged();
|
||||
redraw();
|
||||
}
|
||||
|
||||
std::string CAltarCreatures::getTraderText()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.484");
|
||||
message.replaceNamePlural(CreatureID(bidTradePanel->getSelectedItemId()));
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@ -9,29 +9,28 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CTradeBase.h"
|
||||
#include "CMarketBase.h"
|
||||
|
||||
class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling
|
||||
class CAltarCreatures :
|
||||
public CExperienceAltar, public CCreaturesSelling, public CMarketSlider, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
||||
void updateSlots();
|
||||
void update() override;
|
||||
void deselect() override;
|
||||
TExpType calcExpAltarForHero() override;
|
||||
void makeDeal() override;
|
||||
void sacrificeAll() override;
|
||||
void updateAltarSlot(std::shared_ptr<CTradeableItem> slot);
|
||||
|
||||
private:
|
||||
std::shared_ptr<CButton> maxUnits;
|
||||
std::vector<int> unitsOnAltar;
|
||||
std::vector<int> expPerUnit;
|
||||
std::shared_ptr<CLabel> lSubtitle;
|
||||
std::shared_ptr<CLabel> rSubtitle;
|
||||
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot);
|
||||
void readExpValues();
|
||||
void updateControls();
|
||||
void updateSubtitlesForSelected();
|
||||
void onOfferSliderMoved(int newVal);
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSide) override;
|
||||
void highlightingChanged() override;
|
||||
void onOfferSliderMoved(int newVal) override;
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<TradePanelBase> & curPanel) override;
|
||||
std::string getTraderText() override;
|
||||
};
|
||||
|
126
client/widgets/markets/CArtifactsBuying.cpp
Normal file
126
client/widgets/markets/CArtifactsBuying.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* CArtifactsBuying.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsBuying.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
#include "../../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, bidTradePanel);})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
std::string title;
|
||||
if(auto townMarket = dynamic_cast<const CGTownInstance*>(market))
|
||||
title = (*CGI->townh)[townMarket->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
|
||||
else
|
||||
title = CGI->generaltexth->allTexts[349];
|
||||
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title));
|
||||
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this](){CArtifactsBuying::makeDeal();});
|
||||
labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(39, 184));
|
||||
bidTradePanel->showcaseSlot->image->moveTo(pos.topLeft() + Point(141, 454));
|
||||
|
||||
// Artifacts panel
|
||||
offerTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot)
|
||||
{
|
||||
CArtifactsBuying::onSlotClickPressed(newSlot, offerTradePanel);
|
||||
}, [this]()
|
||||
{
|
||||
CMarketBase::updateSubtitlesForBid(EMarketMode::RESOURCE_ARTIFACT, bidTradePanel->getSelectedItemId());
|
||||
}, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT));
|
||||
offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
|
||||
{
|
||||
return vstd::contains(this->market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
|
||||
};
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(328, 181));
|
||||
|
||||
CMarketBase::update();
|
||||
CArtifactsBuying::deselect();
|
||||
}
|
||||
|
||||
void CArtifactsBuying::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
}
|
||||
|
||||
void CArtifactsBuying::makeDeal()
|
||||
{
|
||||
if(ArtifactID(offerTradePanel->getSelectedItemId()).toArtifact()->canBePutAt(hero))
|
||||
{
|
||||
LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_ARTIFACT, GameResID(bidTradePanel->getSelectedItemId()),
|
||||
ArtifactID(offerTradePanel->getSelectedItemId()), offerQty, hero);
|
||||
CMarketTraderText::makeDeal();
|
||||
deselect();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("core.genrltxt.326"));
|
||||
}
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CArtifactsBuying::getShowcasesParams() const
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
ShowcaseParams {std::to_string(deal->isBlocked() ? 0 : bidQty), bidTradePanel->getSelectedItemId()},
|
||||
ShowcaseParams {std::to_string(deal->isBlocked() ? 0 : offerQty), CGI->artifacts()->getByIndex(offerTradePanel->getSelectedItemId())->getIconIndex()}
|
||||
};
|
||||
else
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CArtifactsBuying::highlightingChanged()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
market->getOffer(bidTradePanel->getSelectedItemId(), offerTradePanel->getSelectedItemId(), bidQty, offerQty, EMarketMode::RESOURCE_ARTIFACT);
|
||||
deal->block(LOCPLINT->cb->getResourceAmount(GameResID(bidTradePanel->getSelectedItemId())) >= bidQty ? false : true);
|
||||
}
|
||||
CMarketBase::highlightingChanged();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
std::string CArtifactsBuying::getTraderText()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.267");
|
||||
message.replaceName(ArtifactID(offerTradePanel->getSelectedItemId()));
|
||||
message.replaceNumber(bidQty);
|
||||
message.replaceTextID(bidQty == 1 ? "core.genrltxt.161" : "core.genrltxt.160");
|
||||
message.replaceName(GameResID(bidTradePanel->getSelectedItemId()));
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return madeTransaction ? CGI->generaltexth->allTexts[162] : CGI->generaltexth->allTexts[163];
|
||||
}
|
||||
}
|
25
client/widgets/markets/CArtifactsBuying.h
Normal file
25
client/widgets/markets/CArtifactsBuying.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* CArtifactsBuying.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 "CMarketBase.h"
|
||||
|
||||
class CArtifactsBuying : public CResourcesSelling, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
|
||||
private:
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void highlightingChanged() override;
|
||||
std::string getTraderText() override;
|
||||
};
|
169
client/widgets/markets/CArtifactsSelling.cpp
Normal file
169
client/widgets/markets/CArtifactsSelling.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* CArtifactsSelling.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CArtifactsSelling.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CArtifactInstance.h"
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
#include "../../../lib/mapObjects/CGTownInstance.h"
|
||||
|
||||
CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CResourcesBuying(
|
||||
[this](const std::shared_ptr<CTradeableItem> & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, offerTradePanel);},
|
||||
[this](){CArtifactsSelling::updateSubtitles();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
|
||||
(*CGI->townh)[dynamic_cast<const CGTownInstance*>(market)->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated()));
|
||||
labels.push_back(std::make_shared<CLabel>(155, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
|
||||
deal = std::make_shared<CButton>(dealButtonPos, AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();});
|
||||
bidSelectedSlot = std::make_shared<CTradeableItem>(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0);
|
||||
|
||||
// Market resources panel
|
||||
assert(offerTradePanel);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(326, 184));
|
||||
offerTradePanel->showcaseSlot->moveTo(pos.topLeft() + Point(409, 473));
|
||||
offerTradePanel->showcaseSlot->subtitle->moveBy(Point(0, 1));
|
||||
|
||||
// Hero's artifacts
|
||||
heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46), offerTradePanel->selectionWidth);
|
||||
heroArts->setHero(hero);
|
||||
heroArts->selectArtCallback = [this](const CArtPlace * artPlace)
|
||||
{
|
||||
assert(artPlace);
|
||||
selectedHeroSlot = artPlace->slot;
|
||||
CArtifactsSelling::highlightingChanged();
|
||||
CIntObject::redraw();
|
||||
};
|
||||
|
||||
CArtifactsSelling::updateShowcases();
|
||||
CArtifactsSelling::deselect();
|
||||
}
|
||||
|
||||
void CArtifactsSelling::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
selectedHeroSlot = ArtifactPosition::PRE_FIRST;
|
||||
heroArts->unmarkSlots();
|
||||
bidSelectedSlot->clear();
|
||||
}
|
||||
|
||||
void CArtifactsSelling::makeDeal()
|
||||
{
|
||||
const auto art = hero->getArt(selectedHeroSlot);
|
||||
assert(art);
|
||||
LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_RESOURCE, art->getId(), GameResID(offerTradePanel->getSelectedItemId()), offerQty, hero);
|
||||
CMarketTraderText::makeDeal();
|
||||
}
|
||||
|
||||
void CArtifactsSelling::updateShowcases()
|
||||
{
|
||||
const auto art = hero->getArt(selectedHeroSlot);
|
||||
if(art && offerTradePanel->isHighlighted())
|
||||
{
|
||||
bidSelectedSlot->image->enable();
|
||||
bidSelectedSlot->setID(art->getTypeId().num);
|
||||
bidSelectedSlot->image->setFrame(CGI->artifacts()->getByIndex(art->getTypeId())->getIconIndex());
|
||||
bidSelectedSlot->subtitle->setText(std::to_string(bidQty));
|
||||
}
|
||||
else
|
||||
{
|
||||
bidSelectedSlot->clear();
|
||||
}
|
||||
CMarketBase::updateShowcases();
|
||||
}
|
||||
|
||||
void CArtifactsSelling::update()
|
||||
{
|
||||
CMarketBase::update();
|
||||
if(selectedHeroSlot != ArtifactPosition::PRE_FIRST)
|
||||
{
|
||||
if(hero->getArt(selectedHeroSlot) == nullptr)
|
||||
{
|
||||
deselect();
|
||||
selectedHeroSlot = ArtifactPosition::PRE_FIRST;
|
||||
}
|
||||
else
|
||||
{
|
||||
heroArts->getArtPlace(selectedHeroSlot)->selectSlot(true);
|
||||
}
|
||||
highlightingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<CArtifactsOfHeroMarket> CArtifactsSelling::getAOHset() const
|
||||
{
|
||||
return heroArts;
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CArtifactsSelling::getShowcasesParams() const
|
||||
{
|
||||
if(hero->getArt(selectedHeroSlot) && offerTradePanel->isHighlighted())
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
std::nullopt,
|
||||
ShowcaseParams {std::to_string(offerQty), offerTradePanel->getSelectedItemId()}
|
||||
};
|
||||
else
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CArtifactsSelling::updateSubtitles()
|
||||
{
|
||||
const auto art = this->hero->getArt(selectedHeroSlot);
|
||||
const int bidId = art == nullptr ? -1 : art->getTypeId().num;
|
||||
CMarketBase::updateSubtitlesForBid(EMarketMode::ARTIFACT_RESOURCE, bidId);
|
||||
}
|
||||
|
||||
void CArtifactsSelling::highlightingChanged()
|
||||
{
|
||||
const auto art = hero->getArt(selectedHeroSlot);
|
||||
if(art && offerTradePanel->isHighlighted())
|
||||
{
|
||||
market->getOffer(art->getTypeId(), offerTradePanel->getSelectedItemId(), bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
|
||||
deal->block(false);
|
||||
}
|
||||
CMarketBase::highlightingChanged();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
std::string CArtifactsSelling::getTraderText()
|
||||
{
|
||||
const auto art = hero->getArt(selectedHeroSlot);
|
||||
if(art && offerTradePanel->isHighlighted())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.268");
|
||||
message.replaceNumber(offerQty);
|
||||
message.replaceRawString(offerQty == 1 ? CGI->generaltexth->allTexts[161] : CGI->generaltexth->allTexts[160]);
|
||||
message.replaceName(GameResID(offerTradePanel->getSelectedItemId()));
|
||||
message.replaceName(art->getTypeId());
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return madeTransaction ? CGI->generaltexth->allTexts[162] : CGI->generaltexth->allTexts[163];
|
||||
}
|
||||
}
|
35
client/widgets/markets/CArtifactsSelling.h
Normal file
35
client/widgets/markets/CArtifactsSelling.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* CArtifactsSelling.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 "../CArtifactsOfHeroMarket.h"
|
||||
#include "CMarketBase.h"
|
||||
|
||||
class CArtifactsSelling : public CResourcesBuying, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
void updateShowcases() override;
|
||||
void update() override;
|
||||
std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<CArtifactsOfHeroMarket> heroArts;
|
||||
std::shared_ptr<CLabel> bidSelectedSubtitle;
|
||||
std::shared_ptr<CTradeableItem> bidSelectedSlot;
|
||||
ArtifactPosition selectedHeroSlot;
|
||||
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void updateSubtitles();
|
||||
void highlightingChanged() override;
|
||||
std::string getTraderText() override;
|
||||
};
|
124
client/widgets/markets/CFreelancerGuild.cpp
Normal file
124
client/widgets/markets/CFreelancerGuild.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* CFreelancerGuild.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CFreelancerGuild.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/MetaString.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
|
||||
CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CResourcesBuying(
|
||||
[this](const std::shared_ptr<CTradeableItem> & heroSlot){CFreelancerGuild::onSlotClickPressed(heroSlot, offerTradePanel);},
|
||||
[this](){CMarketBase::updateSubtitlesForBid(EMarketMode::CREATURE_RESOURCE, bidTradePanel->getSelectedItemId());})
|
||||
, CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
|
||||
VLC->generaltexth->translate("object.core.freelancersGuild.name")));
|
||||
labels.emplace_back(std::make_shared<CLabel>(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
|
||||
deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();});
|
||||
offerSlider->moveTo(pos.topLeft() + Point(232, 489));
|
||||
|
||||
// Hero creatures panel
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(45, 123));
|
||||
bidTradePanel->showcaseSlot->subtitle->moveBy(Point(0, -1));
|
||||
bidTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
|
||||
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
|
||||
{
|
||||
CFreelancerGuild::onSlotClickPressed(heroSlot, bidTradePanel);
|
||||
};
|
||||
});
|
||||
|
||||
CFreelancerGuild::deselect();
|
||||
}
|
||||
|
||||
void CFreelancerGuild::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CMarketSlider::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
}
|
||||
|
||||
void CFreelancerGuild::makeDeal()
|
||||
{
|
||||
if(auto toTrade = offerSlider->getValue(); toTrade != 0)
|
||||
{
|
||||
LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(bidTradePanel->highlightedSlot->serial), GameResID(offerTradePanel->getSelectedItemId()), bidQty * toTrade, hero);
|
||||
CMarketTraderText::makeDeal();
|
||||
deselect();
|
||||
}
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CFreelancerGuild::getShowcasesParams() const
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
ShowcaseParams {std::to_string(bidQty * offerSlider->getValue()), CGI->creatures()->getByIndex(bidTradePanel->getSelectedItemId())->getIconIndex()},
|
||||
ShowcaseParams {std::to_string(offerQty * offerSlider->getValue()), offerTradePanel->getSelectedItemId()}
|
||||
};
|
||||
else
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CFreelancerGuild::highlightingChanged()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
market->getOffer(bidTradePanel->getSelectedItemId(), offerTradePanel->getSelectedItemId(), bidQty, offerQty, EMarketMode::CREATURE_RESOURCE);
|
||||
offerSlider->setAmount((hero->getStackCount(SlotID(bidTradePanel->highlightedSlot->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack() ? 1 : 0)) / bidQty);
|
||||
offerSlider->scrollTo(0);
|
||||
offerSlider->block(false);
|
||||
maxAmount->block(false);
|
||||
deal->block(false);
|
||||
}
|
||||
CMarketBase::highlightingChanged();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
std::string CFreelancerGuild::getTraderText()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.269");
|
||||
message.replaceNumber(offerQty);
|
||||
message.replaceRawString(offerQty == 1 ? CGI->generaltexth->allTexts[161] : CGI->generaltexth->allTexts[160]);
|
||||
message.replaceName(GameResID(offerTradePanel->getSelectedItemId()));
|
||||
message.replaceNumber(bidQty);
|
||||
if(bidQty == 1)
|
||||
message.replaceNameSingular(bidTradePanel->getSelectedItemId());
|
||||
else
|
||||
message.replaceNamePlural(bidTradePanel->getSelectedItemId());
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return madeTransaction ? CGI->generaltexth->allTexts[162] : CGI->generaltexth->allTexts[163];
|
||||
}
|
||||
}
|
26
client/widgets/markets/CFreelancerGuild.h
Normal file
26
client/widgets/markets/CFreelancerGuild.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* CFreelancerGuild.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 "CMarketBase.h"
|
||||
|
||||
class CFreelancerGuild :
|
||||
public CCreaturesSelling , public CResourcesBuying, public CMarketSlider, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
|
||||
private:
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void highlightingChanged() override;
|
||||
std::string getTraderText() override;
|
||||
};
|
244
client/widgets/markets/CMarketBase.cpp
Normal file
244
client/widgets/markets/CMarketBase.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* CMarketBase.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CMarketBase.h"
|
||||
|
||||
#include "../MiscWidgets.h"
|
||||
|
||||
#include "../Images.h"
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../../lib/CHeroHandler.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
|
||||
CMarketBase::CMarketBase(const IMarket * market, const CGHeroInstance * hero)
|
||||
: market(market)
|
||||
, hero(hero)
|
||||
{
|
||||
}
|
||||
|
||||
void CMarketBase::deselect()
|
||||
{
|
||||
if(bidTradePanel && bidTradePanel->highlightedSlot)
|
||||
{
|
||||
bidTradePanel->highlightedSlot->selectSlot(false);
|
||||
bidTradePanel->highlightedSlot.reset();
|
||||
}
|
||||
if(offerTradePanel && offerTradePanel->highlightedSlot)
|
||||
{
|
||||
offerTradePanel->highlightedSlot->selectSlot(false);
|
||||
offerTradePanel->highlightedSlot.reset();
|
||||
}
|
||||
deal->block(true);
|
||||
bidQty = 0;
|
||||
offerQty = 0;
|
||||
updateShowcases();
|
||||
}
|
||||
|
||||
void CMarketBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<TradePanelBase> & curPanel)
|
||||
{
|
||||
assert(newSlot);
|
||||
assert(curPanel);
|
||||
if(newSlot == curPanel->highlightedSlot)
|
||||
return;
|
||||
|
||||
curPanel->onSlotClickPressed(newSlot);
|
||||
highlightingChanged();
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CMarketBase::update()
|
||||
{
|
||||
if(bidTradePanel)
|
||||
bidTradePanel->update();
|
||||
if(offerTradePanel)
|
||||
offerTradePanel->update();
|
||||
}
|
||||
|
||||
void CMarketBase::updateSubtitlesForBid(EMarketMode marketMode, int bidId)
|
||||
{
|
||||
if(bidId == -1)
|
||||
{
|
||||
if(offerTradePanel)
|
||||
offerTradePanel->clearSubtitles();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const auto & slot : offerTradePanel->slots)
|
||||
{
|
||||
int slotBidQty = 0;
|
||||
int slotOfferQty = 0;
|
||||
market->getOffer(bidId, slot->id, slotBidQty, slotOfferQty, marketMode);
|
||||
offerTradePanel->updateOffer(*slot, slotBidQty, slotOfferQty);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void CMarketBase::updateShowcases()
|
||||
{
|
||||
const auto updateSelectedBody = [](const std::shared_ptr<TradePanelBase> & tradePanel, const std::optional<const ShowcaseParams> & params)
|
||||
{
|
||||
if(params.has_value())
|
||||
{
|
||||
tradePanel->setShowcaseSubtitle(params.value().text);
|
||||
tradePanel->showcaseSlot->image->enable();
|
||||
tradePanel->showcaseSlot->image->setFrame(params.value().imageIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
tradePanel->showcaseSlot->clear();
|
||||
}
|
||||
};
|
||||
|
||||
const auto params = getShowcasesParams();
|
||||
if(bidTradePanel)
|
||||
updateSelectedBody(bidTradePanel, params.bidParams);
|
||||
if(offerTradePanel)
|
||||
updateSelectedBody(offerTradePanel, params.offerParams);
|
||||
}
|
||||
|
||||
void CMarketBase::highlightingChanged()
|
||||
{
|
||||
offerTradePanel->update();
|
||||
updateShowcases();
|
||||
}
|
||||
|
||||
CExperienceAltar::CExperienceAltar()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
// Experience needed to reach next level
|
||||
texts.emplace_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[475], Rect(15, 415, 125, 50), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
|
||||
// Total experience on the Altar
|
||||
texts.emplace_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
|
||||
expToLevel = std::make_shared<CLabel>(76, 477, FONT_SMALL, ETextAlignment::CENTER);
|
||||
expForHero = std::make_shared<CLabel>(76, 545, FONT_SMALL, ETextAlignment::CENTER);
|
||||
}
|
||||
|
||||
void CExperienceAltar::deselect()
|
||||
{
|
||||
expForHero->setText(std::to_string(0));
|
||||
}
|
||||
|
||||
void CExperienceAltar::update()
|
||||
{
|
||||
expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(hero->exp) + 1) - hero->exp));
|
||||
}
|
||||
|
||||
CCreaturesSelling::CCreaturesSelling()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
assert(hero);
|
||||
CreaturesPanel::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)));
|
||||
}
|
||||
bidTradePanel = std::make_shared<CreaturesPanel>(nullptr, slots);
|
||||
bidTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitles, this);
|
||||
}
|
||||
|
||||
bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot) const
|
||||
{
|
||||
return hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
|
||||
}
|
||||
|
||||
void CCreaturesSelling::updateSubtitles() const
|
||||
{
|
||||
for(const auto & heroSlot : bidTradePanel->slots)
|
||||
heroSlot->subtitle->setText(std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial))));
|
||||
}
|
||||
|
||||
CResourcesBuying::CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
offerTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, updSlotsCallback);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(327, 182));
|
||||
labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
|
||||
}
|
||||
|
||||
CResourcesSelling::CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
bidTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, std::bind(&CResourcesSelling::updateSubtitles, this));
|
||||
labels.emplace_back(std::make_shared<CLabel>(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
|
||||
}
|
||||
|
||||
void CResourcesSelling::updateSubtitles() const
|
||||
{
|
||||
for(const auto & slot : bidTradePanel->slots)
|
||||
slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial))));
|
||||
}
|
||||
|
||||
CMarketSlider::CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
offerSlider = std::make_shared<CSlider>(Point(230, 489), 137, movingCallback, 0, 0, 0, Orientation::HORIZONTAL);
|
||||
maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
|
||||
[this]()
|
||||
{
|
||||
offerSlider->scrollToMax();
|
||||
});
|
||||
}
|
||||
|
||||
void CMarketSlider::deselect()
|
||||
{
|
||||
maxAmount->block(true);
|
||||
offerSlider->scrollTo(0);
|
||||
offerSlider->block(true);
|
||||
}
|
||||
|
||||
void CMarketSlider::onOfferSliderMoved(int newVal)
|
||||
{
|
||||
if(bidTradePanel->highlightedSlot && offerTradePanel->highlightedSlot)
|
||||
{
|
||||
offerSlider->scrollTo(newVal);
|
||||
updateShowcases();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
|
||||
CMarketTraderText::CMarketTraderText(const Point & pos, const EFonts & font, const ColorRGBA & color)
|
||||
: madeTransaction(false)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
traderText = std::make_shared<CTextBox>("", Rect(pos, traderTextDimensions), 0, font, ETextAlignment::CENTER, color);
|
||||
}
|
||||
|
||||
void CMarketTraderText::deselect()
|
||||
{
|
||||
highlightingChanged();
|
||||
}
|
||||
|
||||
void CMarketTraderText::makeDeal()
|
||||
{
|
||||
madeTransaction = true;
|
||||
}
|
||||
|
||||
void CMarketTraderText::highlightingChanged()
|
||||
{
|
||||
traderText->setText(getTraderText());
|
||||
}
|
128
client/widgets/markets/CMarketBase.h
Normal file
128
client/widgets/markets/CMarketBase.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* CMarketBase.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 "TradePanels.h"
|
||||
#include "../../widgets/Slider.h"
|
||||
#include "../../render/EFont.h"
|
||||
#include "../../render/Colors.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class IMarket;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CMarketBase : public CIntObject
|
||||
{
|
||||
public:
|
||||
struct ShowcaseParams
|
||||
{
|
||||
std::string text;
|
||||
int imageIndex;
|
||||
};
|
||||
struct MarketShowcasesParams
|
||||
{
|
||||
std::optional<const ShowcaseParams> bidParams;
|
||||
std::optional<const ShowcaseParams> offerParams;
|
||||
};
|
||||
using ShowcasesParamsFunctor = std::function<const MarketShowcasesParams()>;
|
||||
|
||||
const IMarket * market;
|
||||
const CGHeroInstance * hero;
|
||||
|
||||
std::shared_ptr<TradePanelBase> bidTradePanel;
|
||||
std::shared_ptr<TradePanelBase> offerTradePanel;
|
||||
|
||||
std::shared_ptr<CButton> deal;
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::vector<std::shared_ptr<CTextBox>> texts;
|
||||
int bidQty;
|
||||
int offerQty;
|
||||
const Point dealButtonPos = Point(270, 520);
|
||||
const Point titlePos = Point(299, 27);
|
||||
|
||||
CMarketBase(const IMarket * market, const CGHeroInstance * hero);
|
||||
virtual void makeDeal() = 0;
|
||||
virtual void deselect();
|
||||
virtual void update();
|
||||
|
||||
protected:
|
||||
virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<TradePanelBase> & curPanel);
|
||||
virtual void updateSubtitlesForBid(EMarketMode marketMode, int bidId);
|
||||
virtual void updateShowcases();
|
||||
virtual MarketShowcasesParams getShowcasesParams() const = 0;
|
||||
virtual void highlightingChanged();
|
||||
};
|
||||
|
||||
// Market subclasses
|
||||
class CExperienceAltar : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<CLabel> expToLevel;
|
||||
std::shared_ptr<CLabel> expForHero;
|
||||
std::shared_ptr<CButton> sacrificeAllButton;
|
||||
|
||||
CExperienceAltar();
|
||||
void deselect() override;
|
||||
void update() override;
|
||||
virtual void sacrificeAll() = 0;
|
||||
virtual TExpType calcExpAltarForHero() = 0;
|
||||
};
|
||||
|
||||
class CCreaturesSelling : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
CCreaturesSelling();
|
||||
bool slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot) const;
|
||||
void updateSubtitles() const;
|
||||
};
|
||||
|
||||
class CResourcesBuying : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback);
|
||||
};
|
||||
|
||||
class CResourcesSelling : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
explicit CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
|
||||
void updateSubtitles() const;
|
||||
};
|
||||
|
||||
class CMarketSlider : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<CSlider> offerSlider;
|
||||
std::shared_ptr<CButton> maxAmount;
|
||||
const Point dealButtonPosWithSlider = Point(306, 520);
|
||||
|
||||
explicit CMarketSlider(const CSlider::SliderMovingFunctor & movingCallback);
|
||||
void deselect() override;
|
||||
virtual void onOfferSliderMoved(int newVal);
|
||||
};
|
||||
|
||||
class CMarketTraderText : virtual public CMarketBase
|
||||
{
|
||||
public:
|
||||
CMarketTraderText(const Point & pos = Point(316, 48), const EFonts & font = EFonts::FONT_SMALL, const ColorRGBA & Color = Colors::WHITE);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
|
||||
const Point traderTextDimensions = Point(260, 75);
|
||||
std::shared_ptr<CTextBox> traderText;
|
||||
bool madeTransaction;
|
||||
|
||||
protected:
|
||||
void highlightingChanged() override;
|
||||
virtual std::string getTraderText() = 0;
|
||||
};
|
123
client/widgets/markets/CMarketResources.cpp
Normal file
123
client/widgets/markets/CMarketResources.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* CMarketResources.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CMarketResources.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/MetaString.h"
|
||||
#include "../../../lib/mapObjects/CGMarket.h"
|
||||
|
||||
CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, bidTradePanel);})
|
||||
, CResourcesBuying(
|
||||
[this](const std::shared_ptr<CTradeableItem> & resSlot){CMarketResources::onSlotClickPressed(resSlot, offerTradePanel);},
|
||||
[this](){CMarketResources::updateSubtitles();})
|
||||
, CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
|
||||
deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); });
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(39, 182));
|
||||
|
||||
// Market resources panel
|
||||
assert(offerTradePanel);
|
||||
|
||||
CMarketBase::update();
|
||||
CMarketResources::deselect();
|
||||
}
|
||||
|
||||
void CMarketResources::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CMarketSlider::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
}
|
||||
|
||||
void CMarketResources::makeDeal()
|
||||
{
|
||||
if(auto toTrade = offerSlider->getValue(); toTrade != 0)
|
||||
{
|
||||
LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_RESOURCE, GameResID(bidTradePanel->getSelectedItemId()),
|
||||
GameResID(offerTradePanel->highlightedSlot->id), bidQty * toTrade, hero);
|
||||
CMarketTraderText::makeDeal();
|
||||
deselect();
|
||||
}
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CMarketResources::getShowcasesParams() const
|
||||
{
|
||||
if(bidTradePanel->highlightedSlot && offerTradePanel->highlightedSlot && bidTradePanel->getSelectedItemId() != offerTradePanel->getSelectedItemId())
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
ShowcaseParams {std::to_string(bidQty * offerSlider->getValue()), bidTradePanel->getSelectedItemId()},
|
||||
ShowcaseParams {std::to_string(offerQty * offerSlider->getValue()), offerTradePanel->getSelectedItemId()}
|
||||
};
|
||||
else
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CMarketResources::highlightingChanged()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
market->getOffer(bidTradePanel->getSelectedItemId(), offerTradePanel->getSelectedItemId(), bidQty, offerQty, EMarketMode::RESOURCE_RESOURCE);
|
||||
offerSlider->setAmount(LOCPLINT->cb->getResourceAmount(GameResID(bidTradePanel->getSelectedItemId())) / bidQty);
|
||||
offerSlider->scrollTo(0);
|
||||
const bool isControlsBlocked = bidTradePanel->getSelectedItemId() != offerTradePanel->getSelectedItemId() ? false : true;
|
||||
offerSlider->block(isControlsBlocked);
|
||||
maxAmount->block(isControlsBlocked);
|
||||
deal->block(isControlsBlocked);
|
||||
}
|
||||
CMarketBase::highlightingChanged();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
void CMarketResources::updateSubtitles()
|
||||
{
|
||||
CMarketBase::updateSubtitlesForBid(EMarketMode::RESOURCE_RESOURCE, bidTradePanel->getSelectedItemId());
|
||||
if(bidTradePanel->highlightedSlot)
|
||||
offerTradePanel->slots[bidTradePanel->highlightedSlot->serial]->subtitle->setText(CGI->generaltexth->allTexts[164]); // n/a
|
||||
}
|
||||
|
||||
std::string CMarketResources::getTraderText()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted() &&
|
||||
bidTradePanel->getSelectedItemId() != offerTradePanel->getSelectedItemId())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.157");
|
||||
message.replaceNumber(offerQty);
|
||||
message.replaceRawString(offerQty == 1 ? CGI->generaltexth->allTexts[161] : CGI->generaltexth->allTexts[160]);
|
||||
message.replaceName(GameResID(bidTradePanel->getSelectedItemId()));
|
||||
message.replaceNumber(bidQty);
|
||||
message.replaceRawString(bidQty == 1 ? CGI->generaltexth->allTexts[161] : CGI->generaltexth->allTexts[160]);
|
||||
message.replaceName(GameResID(offerTradePanel->getSelectedItemId()));
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return madeTransaction ? CGI->generaltexth->allTexts[162] : CGI->generaltexth->allTexts[163];
|
||||
}
|
||||
}
|
27
client/widgets/markets/CMarketResources.h
Normal file
27
client/widgets/markets/CMarketResources.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* CMarketResources.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 "CMarketBase.h"
|
||||
|
||||
class CMarketResources :
|
||||
public CResourcesSelling, public CResourcesBuying, public CMarketSlider, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CMarketResources(const IMarket * market, const CGHeroInstance * hero);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
|
||||
private:
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void highlightingChanged() override;
|
||||
void updateSubtitles();
|
||||
std::string getTraderText() override;
|
||||
};
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* CTradeBase.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CTradeBase.h"
|
||||
|
||||
#include "../MiscWidgets.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
|
||||
: market(market)
|
||||
, hero(hero)
|
||||
{
|
||||
}
|
||||
|
||||
void CTradeBase::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove)
|
||||
{
|
||||
for(auto item : toRemove)
|
||||
removeItem(item);
|
||||
}
|
||||
|
||||
void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
|
||||
{
|
||||
rightTradePanel->slots.erase(std::remove(rightTradePanel->slots.begin(), rightTradePanel->slots.end(), item));
|
||||
|
||||
if(hRight == item)
|
||||
hRight.reset();
|
||||
}
|
||||
|
||||
void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
|
||||
{
|
||||
for(auto item : leftTradePanel->slots)
|
||||
if(!hero->getStackCount(SlotID(item->serial)))
|
||||
toRemove.insert(item);
|
||||
}
|
||||
|
||||
void CTradeBase::deselect()
|
||||
{
|
||||
if(hLeft)
|
||||
hLeft->selectSlot(false);
|
||||
if(hRight)
|
||||
hRight->selectSlot(false);
|
||||
hLeft = hRight = nullptr;
|
||||
deal->block(true);
|
||||
}
|
||||
|
||||
void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
|
||||
{
|
||||
if(newSlot == hCurSlot)
|
||||
return;
|
||||
|
||||
if(hCurSlot)
|
||||
hCurSlot->selectSlot(false);
|
||||
hCurSlot = newSlot;
|
||||
newSlot->selectSlot(true);
|
||||
}
|
||||
|
||||
CExperienceAltar::CExperienceAltar()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
// Experience needed to reach next level
|
||||
texts.emplace_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[475], Rect(15, 415, 125, 50), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
|
||||
// Total experience on the Altar
|
||||
texts.emplace_back(std::make_shared<CTextBox>(CGI->generaltexth->allTexts[476], Rect(15, 495, 125, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
|
||||
expToLevel = std::make_shared<CLabel>(75, 477, FONT_SMALL, ETextAlignment::CENTER);
|
||||
expForHero = std::make_shared<CLabel>(75, 545, FONT_SMALL, ETextAlignment::CENTER);
|
||||
}
|
||||
|
||||
CCreaturesSelling::CCreaturesSelling()
|
||||
{
|
||||
assert(hero);
|
||||
CreaturesPanel::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<CreaturesPanel>(nullptr, slots);
|
||||
}
|
||||
|
||||
bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot)
|
||||
{
|
||||
return hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
|
||||
}
|
||||
|
||||
void CCreaturesSelling::updateSubtitle()
|
||||
{
|
||||
for(auto & heroSlot : leftTradePanel->slots)
|
||||
heroSlot->subtitle = std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)));
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* CTradeBase.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 "TradePanels.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class IMarket;
|
||||
class CGHeroInstance;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CButton;
|
||||
class CSlider;
|
||||
|
||||
class CTradeBase
|
||||
{
|
||||
public:
|
||||
const IMarket * market;
|
||||
const CGHeroInstance * hero;
|
||||
|
||||
//all indexes: 1 = left, 0 = right
|
||||
std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
|
||||
std::shared_ptr<TradePanelBase> leftTradePanel;
|
||||
std::shared_ptr<TradePanelBase> rightTradePanel;
|
||||
|
||||
//highlighted items (nullptr if no highlight)
|
||||
std::shared_ptr<CTradeableItem> hLeft;
|
||||
std::shared_ptr<CTradeableItem> hRight;
|
||||
std::shared_ptr<CButton> deal;
|
||||
std::shared_ptr<CSlider> offerSlider;
|
||||
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::vector<std::shared_ptr<CButton>> buttons;
|
||||
std::vector<std::shared_ptr<CTextBox>> texts;
|
||||
|
||||
CTradeBase(const IMarket * market, const CGHeroInstance * hero);
|
||||
void removeItems(const std::set<std::shared_ptr<CTradeableItem>> & toRemove);
|
||||
void removeItem(std::shared_ptr<CTradeableItem> item);
|
||||
void getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove);
|
||||
virtual void makeDeal() = 0;
|
||||
virtual void deselect();
|
||||
virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
|
||||
};
|
||||
|
||||
// Market subclasses
|
||||
class CExperienceAltar : virtual public CTradeBase, virtual public CIntObject
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<CLabel> expToLevel;
|
||||
std::shared_ptr<CLabel> expForHero;
|
||||
std::shared_ptr<CButton> sacrificeAllButton;
|
||||
const Point dealButtonPos = Point(269, 520);
|
||||
|
||||
CExperienceAltar();
|
||||
virtual void sacrificeAll() = 0;
|
||||
virtual TExpType calcExpAltarForHero() = 0;
|
||||
};
|
||||
|
||||
class CCreaturesSelling : virtual public CTradeBase, virtual public CIntObject
|
||||
{
|
||||
public:
|
||||
CCreaturesSelling();
|
||||
bool slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot);
|
||||
void updateSubtitle();
|
||||
};
|
111
client/widgets/markets/CTransferResources.cpp
Normal file
111
client/widgets/markets/CTransferResources.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* CTransferResources.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CTransferResources.h"
|
||||
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/TextControls.h"
|
||||
|
||||
#include "../../CGameInfo.h"
|
||||
#include "../../CPlayerInterface.h"
|
||||
|
||||
#include "../../../CCallback.h"
|
||||
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/MetaString.h"
|
||||
|
||||
CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CMarketBase(market, hero)
|
||||
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, bidTradePanel);})
|
||||
, CMarketSlider([this](int newVal){CMarketSlider::onOfferSliderMoved(newVal);})
|
||||
, CMarketTraderText(Point(28, 48))
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
labels.emplace_back(std::make_shared<CLabel>(titlePos.x, titlePos.y, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
|
||||
labels.emplace_back(std::make_shared<CLabel>(445, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
|
||||
deal = std::make_shared<CButton>(dealButtonPosWithSlider, AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this](){CTransferResources::makeDeal();});
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(40, 183));
|
||||
|
||||
// Players panel
|
||||
offerTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot)
|
||||
{
|
||||
CTransferResources::onSlotClickPressed(heroSlot, offerTradePanel);
|
||||
});
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(333, 84));
|
||||
|
||||
CMarketBase::update();
|
||||
CTransferResources::deselect();
|
||||
}
|
||||
|
||||
void CTransferResources::deselect()
|
||||
{
|
||||
CMarketBase::deselect();
|
||||
CMarketSlider::deselect();
|
||||
CMarketTraderText::deselect();
|
||||
}
|
||||
|
||||
void CTransferResources::makeDeal()
|
||||
{
|
||||
if(auto toTrade = offerSlider->getValue(); toTrade != 0)
|
||||
{
|
||||
LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_PLAYER, GameResID(bidTradePanel->getSelectedItemId()),
|
||||
PlayerColor(offerTradePanel->getSelectedItemId()), toTrade, hero);
|
||||
CMarketTraderText::makeDeal();
|
||||
deselect();
|
||||
}
|
||||
}
|
||||
|
||||
CMarketBase::MarketShowcasesParams CTransferResources::getShowcasesParams() const
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
return MarketShowcasesParams
|
||||
{
|
||||
ShowcaseParams {std::to_string(offerSlider->getValue()), bidTradePanel->getSelectedItemId()},
|
||||
ShowcaseParams {CGI->generaltexth->capColors[offerTradePanel->getSelectedItemId()], offerTradePanel->getSelectedItemId()}
|
||||
};
|
||||
else
|
||||
return MarketShowcasesParams {std::nullopt, std::nullopt};
|
||||
}
|
||||
|
||||
void CTransferResources::highlightingChanged()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
offerSlider->setAmount(LOCPLINT->cb->getResourceAmount(GameResID(bidTradePanel->getSelectedItemId())));
|
||||
offerSlider->scrollTo(0);
|
||||
offerSlider->block(false);
|
||||
maxAmount->block(false);
|
||||
deal->block(false);
|
||||
}
|
||||
CMarketBase::highlightingChanged();
|
||||
CMarketTraderText::highlightingChanged();
|
||||
}
|
||||
|
||||
std::string CTransferResources::getTraderText()
|
||||
{
|
||||
if(bidTradePanel->isHighlighted() && offerTradePanel->isHighlighted())
|
||||
{
|
||||
MetaString message = MetaString::createFromTextID("core.genrltxt.165");
|
||||
message.replaceName(GameResID(bidTradePanel->getSelectedItemId()));
|
||||
message.replaceName(PlayerColor(offerTradePanel->getSelectedItemId()));
|
||||
return message.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return madeTransaction ? CGI->generaltexth->allTexts[166] : CGI->generaltexth->allTexts[167];
|
||||
}
|
||||
}
|
25
client/widgets/markets/CTransferResources.h
Normal file
25
client/widgets/markets/CTransferResources.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* CTransferResources.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 "CMarketBase.h"
|
||||
|
||||
class CTransferResources : public CResourcesSelling, public CMarketSlider, public CMarketTraderText
|
||||
{
|
||||
public:
|
||||
CTransferResources(const IMarket * market, const CGHeroInstance * hero);
|
||||
void deselect() override;
|
||||
void makeDeal() override;
|
||||
|
||||
private:
|
||||
CMarketBase::MarketShowcasesParams getShowcasesParams() const override;
|
||||
void highlightingChanged() override;
|
||||
std::string getTraderText() override;
|
||||
};
|
@ -23,14 +23,11 @@
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial)
|
||||
CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, int Serial)
|
||||
: SelectableSlot(area, Point(1, 1))
|
||||
, artInstance(nullptr)
|
||||
, type(EType(-1)) // set to invalid, will be corrected in setType
|
||||
, id(ID)
|
||||
, serial(Serial)
|
||||
, left(Left)
|
||||
, downSelection(false)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
@ -38,6 +35,7 @@ CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left,
|
||||
addUsedEvents(HOVER);
|
||||
addUsedEvents(SHOW_POPUP);
|
||||
|
||||
subtitle = std::make_shared<CLabel>(0, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
setType(Type);
|
||||
|
||||
this->pos.w = area.w;
|
||||
@ -60,6 +58,30 @@ void CTradeableItem::setType(EType newType)
|
||||
{
|
||||
image = std::make_shared<CAnimImage>(getFilename(), getIndex());
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
subtitle->moveTo(pos.topLeft() + Point(35, 55));
|
||||
image->moveTo(pos.topLeft() + Point(19, 8));
|
||||
break;
|
||||
case EType::CREATURE_PLACEHOLDER:
|
||||
case EType::CREATURE:
|
||||
subtitle->moveTo(pos.topLeft() + Point(30, 77));
|
||||
break;
|
||||
case EType::PLAYER:
|
||||
subtitle->moveTo(pos.topLeft() + Point(31, 76));
|
||||
break;
|
||||
case EType::ARTIFACT_PLACEHOLDER:
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
image->moveTo(pos.topLeft() + Point(0, 1));
|
||||
subtitle->moveTo(pos.topLeft() + Point(21, 56));
|
||||
break;
|
||||
case EType::ARTIFACT_TYPE:
|
||||
subtitle->moveTo(pos.topLeft() + Point(35, 57));
|
||||
image->moveTo(pos.topLeft() + Point(13, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +104,14 @@ void CTradeableItem::setID(int newID)
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeableItem::clear()
|
||||
{
|
||||
setID(-1);
|
||||
image->setFrame(0);
|
||||
image->disable();
|
||||
subtitle->clear();
|
||||
}
|
||||
|
||||
AnimationPath CTradeableItem::getFilename()
|
||||
{
|
||||
switch(type)
|
||||
@ -122,69 +152,15 @@ int CTradeableItem::getIndex()
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeableItem::showAll(Canvas & to)
|
||||
{
|
||||
Point posToBitmap;
|
||||
Point posToSubCenter;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
posToBitmap = Point(19, 9);
|
||||
posToSubCenter = Point(35, 57);
|
||||
break;
|
||||
case EType::CREATURE_PLACEHOLDER:
|
||||
case EType::CREATURE:
|
||||
posToSubCenter = Point(29, 77);
|
||||
break;
|
||||
case EType::PLAYER:
|
||||
posToSubCenter = Point(31, 77);
|
||||
break;
|
||||
case EType::ARTIFACT_PLACEHOLDER:
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
posToSubCenter = Point(22, 51);
|
||||
if (downSelection)
|
||||
posToSubCenter.y += 8;
|
||||
break;
|
||||
case EType::ARTIFACT_TYPE:
|
||||
posToSubCenter = Point(35, 57);
|
||||
posToBitmap = Point(13, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if(image)
|
||||
{
|
||||
image->moveTo(pos.topLeft() + posToBitmap);
|
||||
CIntObject::showAll(to);
|
||||
}
|
||||
|
||||
to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle);
|
||||
}
|
||||
|
||||
void CTradeableItem::clickPressed(const Point & cursorPosition)
|
||||
{
|
||||
if(clickPressedCallback)
|
||||
clickPressedCallback(shared_from_this());
|
||||
}
|
||||
|
||||
void CTradeableItem::showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to)
|
||||
{
|
||||
Rect oldPos = pos;
|
||||
std::string oldSub = subtitle;
|
||||
downSelection = true;
|
||||
|
||||
moveTo(dstPos);
|
||||
subtitle = customSub;
|
||||
showAll(to);
|
||||
|
||||
downSelection = false;
|
||||
moveTo(oldPos.topLeft());
|
||||
subtitle = oldSub;
|
||||
}
|
||||
|
||||
void CTradeableItem::hover(bool on)
|
||||
{
|
||||
if(!on)
|
||||
if(!on || id == -1)
|
||||
{
|
||||
GH.statusbar()->clear();
|
||||
return;
|
||||
@ -196,12 +172,19 @@ void CTradeableItem::hover(bool on)
|
||||
case EType::CREATURE_PLACEHOLDER:
|
||||
GH.statusbar()->write(boost::str(boost::format(CGI->generaltexth->allTexts[481]) % CGI->creh->objects[id]->getNamePluralTranslated()));
|
||||
break;
|
||||
case EType::ARTIFACT_TYPE:
|
||||
case EType::ARTIFACT_PLACEHOLDER:
|
||||
if(id < 0)
|
||||
GH.statusbar()->write(CGI->generaltexth->zelp[582].first);
|
||||
else
|
||||
GH.statusbar()->write(CGI->artifacts()->getByIndex(id)->getNameTranslated());
|
||||
break;
|
||||
case EType::RESOURCE:
|
||||
GH.statusbar()->write(CGI->generaltexth->restypes[id]);
|
||||
break;
|
||||
case EType::PLAYER:
|
||||
GH.statusbar()->write(CGI->generaltexth->capColors[id]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,51 +204,11 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition)
|
||||
}
|
||||
}
|
||||
|
||||
std::string CTradeableItem::getName(int number) const
|
||||
void TradePanelBase::update()
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case EType::PLAYER:
|
||||
return CGI->generaltexth->capColors[id];
|
||||
case EType::RESOURCE:
|
||||
return CGI->generaltexth->restypes[id];
|
||||
case EType::CREATURE:
|
||||
if (number == 1)
|
||||
return CGI->creh->objects[id]->getNameSingularTranslated();
|
||||
else
|
||||
return CGI->creh->objects[id]->getNamePluralTranslated();
|
||||
case EType::ARTIFACT_TYPE:
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
return CGI->artifacts()->getByIndex(id)->getNameTranslated();
|
||||
}
|
||||
logGlobal->error("Invalid trade item type: %d", (int)type);
|
||||
return "";
|
||||
}
|
||||
if(deleteSlotsCheck)
|
||||
slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end());
|
||||
|
||||
const CArtifactInstance * CTradeableItem::getArtInstance() const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case EType::ARTIFACT_PLACEHOLDER:
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
return artInstance;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeableItem::setArtInstance(const CArtifactInstance * art)
|
||||
{
|
||||
assert(type == EType::ARTIFACT_PLACEHOLDER || type == EType::ARTIFACT_INSTANCE);
|
||||
artInstance = art;
|
||||
if(art)
|
||||
setID(art->getTypeId());
|
||||
else
|
||||
setID(-1);
|
||||
}
|
||||
|
||||
void TradePanelBase::updateSlots()
|
||||
{
|
||||
if(updateSlotsCallback)
|
||||
updateSlotsCallback();
|
||||
}
|
||||
@ -279,42 +222,68 @@ void TradePanelBase::deselect()
|
||||
void TradePanelBase::clearSubtitles()
|
||||
{
|
||||
for(const auto & slot : slots)
|
||||
slot->subtitle.clear();
|
||||
slot->subtitle->clear();
|
||||
}
|
||||
|
||||
void TradePanelBase::updateOffer(CTradeableItem & slot, int cost, int qty)
|
||||
{
|
||||
slot.subtitle = std::to_string(qty);
|
||||
std::string subtitle = std::to_string(qty);
|
||||
if(cost != 1)
|
||||
{
|
||||
slot.subtitle.append("/");
|
||||
slot.subtitle.append(std::to_string(cost));
|
||||
subtitle.append("/");
|
||||
subtitle.append(std::to_string(cost));
|
||||
}
|
||||
slot.subtitle->setText(subtitle);
|
||||
}
|
||||
|
||||
void TradePanelBase::deleteSlots()
|
||||
void TradePanelBase::setShowcaseSubtitle(const std::string & text)
|
||||
{
|
||||
if(deleteSlotsCheck)
|
||||
slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end());
|
||||
showcaseSlot->subtitle->setText(text);
|
||||
}
|
||||
|
||||
ResourcesPanel::ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles)
|
||||
int TradePanelBase::getSelectedItemId() const
|
||||
{
|
||||
if(highlightedSlot)
|
||||
return highlightedSlot->id;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TradePanelBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot)
|
||||
{
|
||||
assert(vstd::contains(slots, newSlot));
|
||||
if(newSlot == highlightedSlot)
|
||||
return;
|
||||
|
||||
if(highlightedSlot)
|
||||
highlightedSlot->selectSlot(false);
|
||||
highlightedSlot = newSlot;
|
||||
newSlot->selectSlot(true);
|
||||
}
|
||||
|
||||
bool TradePanelBase::isHighlighted() const
|
||||
{
|
||||
return getSelectedItemId() != -1;
|
||||
}
|
||||
|
||||
ResourcesPanel::ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const UpdateSlotsFunctor & updateSubtitles)
|
||||
{
|
||||
assert(resourcesForTrade.size() == slotsPos.size());
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
for(const auto & res : resourcesForTrade)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension),
|
||||
EType::RESOURCE, res.num, true, res.num));
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension), EType::RESOURCE, res.num, res.num));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
updateSlotsCallback = updateSubtitles;
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::RESOURCE, 0, 0);
|
||||
}
|
||||
|
||||
ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||
const std::vector<TradeItemBuy> & arts)
|
||||
ArtifactsPanel::ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts)
|
||||
{
|
||||
assert(slotsForTrade == slotsPos.size());
|
||||
assert(slotsForTrade == arts.size());
|
||||
@ -326,15 +295,17 @@ ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedC
|
||||
if(artType != ArtifactID::NONE)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotIdx], slotDimension),
|
||||
EType::ARTIFACT_TYPE, artType, false, slotIdx));
|
||||
EType::ARTIFACT_TYPE, artType, slotIdx));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
}
|
||||
updateSlotsCallback = updateSubtitles;
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0);
|
||||
showcaseSlot->subtitle->moveBy(Point(0, 1));
|
||||
}
|
||||
|
||||
PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback)
|
||||
PlayersPanel::PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
|
||||
{
|
||||
assert(PlayerColor::PLAYER_LIMIT_I <= slotsPos.size() + 1);
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
@ -350,15 +321,16 @@ PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallb
|
||||
int slotNum = 0;
|
||||
for(auto & slot : slots)
|
||||
{
|
||||
slot = std::make_shared<CTradeableItem>(Rect(slotsPos[slotNum], slotDimension), EType::PLAYER, players[slotNum].num, false, slotNum);
|
||||
slot = std::make_shared<CTradeableItem>(Rect(slotsPos[slotNum], slotDimension), EType::PLAYER, players[slotNum].num, slotNum);
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
slot->subtitle = CGI->generaltexth->capColors[players[slotNum].num];
|
||||
slot->subtitle->setText(CGI->generaltexth->capColors[players[slotNum].num]);
|
||||
slotNum++;
|
||||
}
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::PLAYER, 0, 0);
|
||||
}
|
||||
|
||||
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots)
|
||||
CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots)
|
||||
{
|
||||
assert(initialSlots.size() <= GameConstants::ARMY_SIZE);
|
||||
assert(slotsPos.size() <= GameConstants::ARMY_SIZE);
|
||||
@ -367,15 +339,16 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
|
||||
for(const auto & [creatureId, slotId, creaturesNum] : initialSlots)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotId.num], slotDimension),
|
||||
creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, creatureId.num, true, slotId));
|
||||
creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, creatureId.num, slotId));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
if(creaturesNum != 0)
|
||||
slot->subtitle = std::to_string(creaturesNum);
|
||||
slot->subtitle->setText(std::to_string(creaturesNum));
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
|
||||
}
|
||||
|
||||
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
|
||||
CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots)
|
||||
{
|
||||
assert(slots.size() <= GameConstants::ARMY_SIZE);
|
||||
@ -384,9 +357,27 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
|
||||
for(const auto & srcSlot : srcSlots)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[srcSlot->serial], srcSlot->pos.dimensions()),
|
||||
emptySlots ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, srcSlot->id, true, srcSlot->serial));
|
||||
emptySlots ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, srcSlot->id, srcSlot->serial));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->subtitle = emptySlots ? "" : srcSlot->subtitle;
|
||||
slot->subtitle->setText(emptySlots ? "" : srcSlot->subtitle->getText());
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
|
||||
}
|
||||
|
||||
ArtifactsAltarPanel::ArtifactsAltarPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
int slotNum = 0;
|
||||
for(auto & altarSlotPos : slotsPos)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, slotNum));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->subtitle->clear();
|
||||
slot->subtitle->moveBy(Point(0, -1));
|
||||
slotNum++;
|
||||
}
|
||||
showcaseSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0);
|
||||
showcaseSlot->subtitle->moveBy(Point(0, 3));
|
||||
}
|
||||
|
@ -27,30 +27,20 @@ public:
|
||||
int getIndex();
|
||||
using ClickPressedFunctor = std::function<void(const std::shared_ptr<CTradeableItem>&)>;
|
||||
|
||||
const CArtifactInstance * artInstance; //holds ptr to artifact instance id type artifact
|
||||
EType type;
|
||||
int id;
|
||||
const int serial;
|
||||
const bool left;
|
||||
std::string subtitle;
|
||||
std::shared_ptr<CLabel> subtitle;
|
||||
ClickPressedFunctor clickPressedCallback;
|
||||
|
||||
void setType(EType newType);
|
||||
void setID(int newID);
|
||||
|
||||
const CArtifactInstance * getArtInstance() const;
|
||||
void setArtInstance(const CArtifactInstance * art);
|
||||
|
||||
bool downSelection;
|
||||
|
||||
void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to);
|
||||
void clear();
|
||||
|
||||
void showPopupWindow(const Point & cursorPosition) override;
|
||||
void hover(bool on) override;
|
||||
void showAll(Canvas & to) override;
|
||||
void clickPressed(const Point & cursorPosition) override;
|
||||
std::string getName(int number = -1) const;
|
||||
CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial);
|
||||
CTradeableItem(const Rect & area, EType Type, int ID, int Serial);
|
||||
};
|
||||
|
||||
class TradePanelBase : public CIntObject
|
||||
@ -62,14 +52,18 @@ public:
|
||||
std::vector<std::shared_ptr<CTradeableItem>> slots;
|
||||
UpdateSlotsFunctor updateSlotsCallback;
|
||||
DeleteSlotsCheck deleteSlotsCheck;
|
||||
std::shared_ptr<CTradeableItem> selected;
|
||||
const int selectionWidth = 2;
|
||||
std::shared_ptr<CTradeableItem> showcaseSlot; // Separate slot that displays the contents for trading
|
||||
std::shared_ptr<CTradeableItem> highlightedSlot; // One of the slots highlighted by a frame
|
||||
|
||||
virtual void updateSlots();
|
||||
virtual void update();
|
||||
virtual void deselect();
|
||||
virtual void clearSubtitles();
|
||||
void updateOffer(CTradeableItem & slot, int, int);
|
||||
void deleteSlots();
|
||||
void setShowcaseSubtitle(const std::string & text);
|
||||
int getSelectedItemId() const;
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot);
|
||||
bool isHighlighted() const;
|
||||
};
|
||||
|
||||
class ResourcesPanel : public TradePanelBase
|
||||
@ -87,25 +81,27 @@ class ResourcesPanel : public TradePanelBase
|
||||
Point(83, 158)
|
||||
};
|
||||
const Point slotDimension = Point(69, 66);
|
||||
const Point selectedPos = Point(83, 267);
|
||||
|
||||
public:
|
||||
ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
|
||||
ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles);
|
||||
};
|
||||
|
||||
class ArtifactsPanel : public TradePanelBase
|
||||
{
|
||||
const std::vector<Point> slotsPos =
|
||||
{
|
||||
Point(0, 0), Point(83, 0), Point(166, 0),
|
||||
Point(0, 79), Point(83, 79), Point(166, 79),
|
||||
Point(0, 0), Point(83, 0), Point(165, 0),
|
||||
Point(0, 79), Point(83, 79), Point(165, 79),
|
||||
Point(83, 158)
|
||||
};
|
||||
const size_t slotsForTrade = 7;
|
||||
const Point slotDimension = Point(69, 66);
|
||||
const Point slotDimension = Point(69, 68);
|
||||
const Point selectedPos = Point(83, 266);
|
||||
|
||||
public:
|
||||
ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||
const std::vector<TradeItemBuy> & arts);
|
||||
ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts);
|
||||
};
|
||||
|
||||
class PlayersPanel : public TradePanelBase
|
||||
@ -117,9 +113,10 @@ class PlayersPanel : public TradePanelBase
|
||||
Point(83, 236)
|
||||
};
|
||||
const Point slotDimension = Point(58, 64);
|
||||
const Point selectedPos = Point(83, 367);
|
||||
|
||||
public:
|
||||
explicit PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback);
|
||||
explicit PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
|
||||
};
|
||||
|
||||
class CreaturesPanel : public TradePanelBase
|
||||
@ -130,12 +127,33 @@ class CreaturesPanel : public TradePanelBase
|
||||
Point(0, 98), Point(83, 98), Point(166, 98),
|
||||
Point(83, 196)
|
||||
};
|
||||
const Point slotDimension = Point(58, 64);
|
||||
const Point slotDimension = Point(59, 64);
|
||||
const Point selectedPos = Point(83, 327);
|
||||
|
||||
public:
|
||||
using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>;
|
||||
|
||||
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots);
|
||||
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
|
||||
CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots);
|
||||
CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots = true);
|
||||
};
|
||||
|
||||
class ArtifactsAltarPanel : public TradePanelBase
|
||||
{
|
||||
const std::vector<Point> slotsPos =
|
||||
{
|
||||
Point(0, 0), Point(54, 0), Point(108, 0),
|
||||
Point(162, 0), Point(216, 0), Point(0, 70),
|
||||
Point(54, 70), Point(108, 70), Point(162, 70),
|
||||
Point(216, 70), Point(0, 140), Point(54, 140),
|
||||
Point(108, 140), Point(162, 140), Point(216, 140),
|
||||
Point(0, 210), Point(54, 210), Point(108, 210),
|
||||
Point(162, 210), Point(216, 210), Point(81, 280),
|
||||
Point(135, 280)
|
||||
};
|
||||
const Point slotDimension = Point(69, 66);
|
||||
const Point selectedPos = Point(-48, 389);
|
||||
|
||||
public:
|
||||
explicit ArtifactsAltarPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
|
||||
};
|
||||
|
@ -1,147 +0,0 @@
|
||||
/*
|
||||
* CAltarWindow.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CAltarWindow.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
|
||||
#include "../lib/networkPacks/ArtifactLocation.h"
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CAltarWindow::CAltarWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode)
|
||||
: CWindowObject(PLAYER_COLORED, ImagePath::builtin(mode == EMarketMode::CREATURE_EXP ? "ALTARMON.bmp" : "ALTRART2.bmp"))
|
||||
, hero(hero)
|
||||
, windowClosedCallback(onWindowClosed)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
assert(mode == EMarketMode::ARTIFACT_EXP || mode == EMarketMode::CREATURE_EXP);
|
||||
if(mode == EMarketMode::ARTIFACT_EXP)
|
||||
createAltarArtifacts(market, hero);
|
||||
else if(mode == EMarketMode::CREATURE_EXP)
|
||||
createAltarCreatures(market, hero);
|
||||
|
||||
updateExpToLevel();
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
}
|
||||
|
||||
void CAltarWindow::updateExpToLevel()
|
||||
{
|
||||
altar->expToLevel->setText(std::to_string(CGI->heroh->reqExp(CGI->heroh->level(altar->hero->exp) + 1) - altar->hero->exp));
|
||||
}
|
||||
|
||||
void CAltarWindow::updateGarrisons()
|
||||
{
|
||||
if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar))
|
||||
altarCreatures->updateSlots();
|
||||
}
|
||||
|
||||
bool CAltarWindow::holdsGarrison(const CArmedInstance * army)
|
||||
{
|
||||
return hero == army;
|
||||
}
|
||||
|
||||
const CGHeroInstance * CAltarWindow::getHero() const
|
||||
{
|
||||
return hero;
|
||||
}
|
||||
|
||||
void CAltarWindow::close()
|
||||
{
|
||||
if(windowClosedCallback)
|
||||
windowClosedCallback();
|
||||
|
||||
CWindowObject::close();
|
||||
}
|
||||
|
||||
void CAltarWindow::createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("ALTRART2.bmp"), PLAYER_COLORED);
|
||||
|
||||
auto altarArtifacts = std::make_shared<CAltarArtifacts>(market, hero);
|
||||
altar = altarArtifacts;
|
||||
artSets.clear();
|
||||
addSetAndCallbacks(altarArtifacts->getAOHset()); altarArtifacts->putBackArtifacts();
|
||||
|
||||
changeModeButton = std::make_shared<CButton>(Point(516, 421), AnimationPath::builtin("ALTSACC.DEF"),
|
||||
CGI->generaltexth->zelp[572], std::bind(&CAltarWindow::createAltarCreatures, this, market, hero));
|
||||
if(altar->hero->getAlignment() == EAlignment::GOOD)
|
||||
changeModeButton->block(true);
|
||||
quitButton = std::make_shared<CButton>(Point(516, 520), AnimationPath::builtin("IOK6432.DEF"),
|
||||
CGI->generaltexth->zelp[568], [this, altarArtifacts]()
|
||||
{
|
||||
altarArtifacts->putBackArtifacts();
|
||||
CAltarWindow::close();
|
||||
}, EShortcut::GLOBAL_RETURN);
|
||||
altar->setRedrawParent(true);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CAltarWindow::createAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("ALTARMON.bmp"), PLAYER_COLORED);
|
||||
|
||||
altar = std::make_shared<CAltarCreatures>(market, hero);
|
||||
|
||||
changeModeButton = std::make_shared<CButton>(Point(516, 421), AnimationPath::builtin("ALTART.DEF"),
|
||||
CGI->generaltexth->zelp[580], std::bind(&CAltarWindow::createAltarArtifacts, this, market, hero));
|
||||
if(altar->hero->getAlignment() == EAlignment::EVIL)
|
||||
changeModeButton->block(true);
|
||||
quitButton = std::make_shared<CButton>(Point(516, 520), AnimationPath::builtin("IOK6432.DEF"),
|
||||
CGI->generaltexth->zelp[568], std::bind(&CAltarWindow::close, this), EShortcut::GLOBAL_RETURN);
|
||||
altar->setRedrawParent(true);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CAltarWindow::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
|
||||
{
|
||||
if(!getState().has_value())
|
||||
return;
|
||||
|
||||
if(auto altarArtifacts = std::static_pointer_cast<CAltarArtifacts>(altar))
|
||||
{
|
||||
if(srcLoc.artHolder == altarArtifacts->getObjId() || destLoc.artHolder == altarArtifacts->getObjId())
|
||||
altarArtifacts->updateSlots();
|
||||
|
||||
if(const auto pickedArt = getPickedArtifact())
|
||||
altarArtifacts->setSelectedArtifact(pickedArt);
|
||||
else
|
||||
altarArtifacts->setSelectedArtifact(nullptr);
|
||||
}
|
||||
CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw);
|
||||
}
|
||||
|
||||
void CAltarWindow::showAll(Canvas & to)
|
||||
{
|
||||
// This func is temporary workaround for compliance with CTradeWindow
|
||||
CWindowObject::showAll(to);
|
||||
|
||||
if(altar->hRight)
|
||||
{
|
||||
altar->hRight->showAllAt(altar->pos.topLeft() + Point(396, 423), "", to);
|
||||
}
|
||||
if(altar->hLeft)
|
||||
{
|
||||
altar->hLeft->showAllAt(altar->pos.topLeft() + Point(150, 423), "", to);
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* CAltarWindow.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 "../widgets/markets/CAltarArtifacts.h"
|
||||
#include "../widgets/markets/CAltarCreatures.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "CWindowObject.h"
|
||||
|
||||
class CAltarWindow : public CWindowObject, public CWindowWithArtifacts, public IGarrisonHolder
|
||||
{
|
||||
public:
|
||||
CAltarWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode);
|
||||
void updateExpToLevel();
|
||||
void updateGarrisons() override;
|
||||
bool holdsGarrison(const CArmedInstance * army) override;
|
||||
const CGHeroInstance * getHero() const;
|
||||
void close() override;
|
||||
|
||||
void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override;
|
||||
void showAll(Canvas & to) override;
|
||||
|
||||
private:
|
||||
const CGHeroInstance * hero;
|
||||
std::shared_ptr<CExperienceAltar> altar;
|
||||
std::shared_ptr<CButton> changeModeButton;
|
||||
std::shared_ptr<CButton> quitButton;
|
||||
std::function<void()> windowClosedCallback;
|
||||
std::shared_ptr<CGStatusBar> statusBar;
|
||||
|
||||
void createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
||||
};
|
@ -11,7 +11,7 @@
|
||||
#include "CCastleInterface.h"
|
||||
|
||||
#include "CHeroWindow.h"
|
||||
#include "CTradeWindow.h"
|
||||
#include "CMarketWindow.h"
|
||||
#include "InfoWindows.h"
|
||||
#include "GUIClasses.h"
|
||||
#include "QuickRecruitmentWindow.h"
|
||||
@ -685,7 +685,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
|
||||
logGlobal->trace("You've clicked on %d", (int)building.toEnum());
|
||||
const CBuilding *b = town->town->buildings.find(building)->second;
|
||||
|
||||
if(building >= BuildingID::DWELL_FIRST)
|
||||
if (building >= BuildingID::DWELL_FIRST)
|
||||
{
|
||||
enterDwelling((building-BuildingID::DWELL_FIRST)%GameConstants::CREATURES_PER_TOWN);
|
||||
}
|
||||
@ -728,7 +728,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
|
||||
case BuildingID::MARKETPLACE:
|
||||
// can't use allied marketplace
|
||||
if (town->getOwner() == LOCPLINT->playerID)
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, town->visitingHero, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, town->visitingHero, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
else
|
||||
enterBuilding(building);
|
||||
break;
|
||||
@ -744,7 +744,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
|
||||
case BuildingID::SPECIAL_1:
|
||||
case BuildingID::SPECIAL_2:
|
||||
case BuildingID::SPECIAL_3:
|
||||
switch(subID)
|
||||
switch (subID)
|
||||
{
|
||||
case BuildingSubID::NONE:
|
||||
enterBuilding(building);
|
||||
@ -756,7 +756,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
|
||||
|
||||
case BuildingSubID::ARTIFACT_MERCHANT:
|
||||
if(town->visitingHero)
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, town->visitingHero, nullptr, EMarketMode::RESOURCE_ARTIFACT);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, town->visitingHero, nullptr, EMarketMode::RESOURCE_ARTIFACT);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->getNameTranslated())); //Only visiting heroes may use the %s.
|
||||
break;
|
||||
@ -767,7 +767,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
|
||||
|
||||
case BuildingSubID::FREELANCERS_GUILD:
|
||||
if(getHero())
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, getHero(), nullptr, EMarketMode::CREATURE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, getHero(), nullptr, EMarketMode::CREATURE_RESOURCE);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->getNameTranslated())); //Only visiting heroes may use the %s.
|
||||
break;
|
||||
@ -1338,7 +1338,7 @@ void CCastleInterface::recreateIcons()
|
||||
{
|
||||
if(town->builtBuildings.count(BuildingID::MARKETPLACE))
|
||||
{
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/ObjectLists.h"
|
||||
#include "../windows/CTradeWindow.h"
|
||||
#include "../windows/CMarketWindow.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
@ -840,7 +840,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
|
||||
{
|
||||
if(town->builtBuildings.count(BuildingID::MARKETPLACE))
|
||||
{
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
GH.windows().createAndPushWindow<CMarketWindow>(town, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
262
client/windows/CMarketWindow.cpp
Normal file
262
client/windows/CMarketWindow.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* CMarketWindow.cpp, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CMarketWindow.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
#include "../widgets/markets/CAltarArtifacts.h"
|
||||
#include "../widgets/markets/CAltarCreatures.h"
|
||||
#include "../widgets/markets/CArtifactsBuying.h"
|
||||
#include "../widgets/markets/CArtifactsSelling.h"
|
||||
#include "../widgets/markets/CFreelancerGuild.h"
|
||||
#include "../widgets/markets/CMarketResources.h"
|
||||
#include "../widgets/markets/CTransferResources.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../../lib/mapObjects/CGMarket.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CMarketWindow::CMarketWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode)
|
||||
: CStatusbarWindow(PLAYER_COLORED)
|
||||
, windowClosedCallback(onWindowClosed)
|
||||
{
|
||||
assert(mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_PLAYER || mode == EMarketMode::CREATURE_RESOURCE ||
|
||||
mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::ARTIFACT_EXP ||
|
||||
mode == EMarketMode::CREATURE_EXP);
|
||||
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
if(mode == EMarketMode::RESOURCE_RESOURCE)
|
||||
createMarketResources(market, hero);
|
||||
else if(mode == EMarketMode::RESOURCE_PLAYER)
|
||||
createTransferResources(market, hero);
|
||||
else if(mode == EMarketMode::CREATURE_RESOURCE)
|
||||
createFreelancersGuild(market, hero);
|
||||
else if(mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||
createArtifactsBuying(market, hero);
|
||||
else if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
createArtifactsSelling(market, hero);
|
||||
else if(mode == EMarketMode::ARTIFACT_EXP)
|
||||
createAltarArtifacts(market, hero);
|
||||
else if(mode == EMarketMode::CREATURE_EXP)
|
||||
createAltarCreatures(market, hero);
|
||||
|
||||
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
}
|
||||
|
||||
void CMarketWindow::updateArtifacts()
|
||||
{
|
||||
assert(marketWidget);
|
||||
marketWidget->update();
|
||||
}
|
||||
|
||||
void CMarketWindow::updateGarrisons()
|
||||
{
|
||||
assert(marketWidget);
|
||||
marketWidget->update();
|
||||
}
|
||||
|
||||
void CMarketWindow::updateResource()
|
||||
{
|
||||
assert(marketWidget);
|
||||
marketWidget->update();
|
||||
}
|
||||
|
||||
void CMarketWindow::updateHero()
|
||||
{
|
||||
assert(marketWidget);
|
||||
marketWidget->update();
|
||||
}
|
||||
|
||||
void CMarketWindow::close()
|
||||
{
|
||||
if(windowClosedCallback)
|
||||
windowClosedCallback();
|
||||
|
||||
CWindowObject::close();
|
||||
}
|
||||
|
||||
bool CMarketWindow::holdsGarrison(const CArmedInstance * army)
|
||||
{
|
||||
assert(marketWidget);
|
||||
return marketWidget->hero == army;
|
||||
}
|
||||
|
||||
void CMarketWindow::artifactRemoved(const ArtifactLocation & artLoc)
|
||||
{
|
||||
marketWidget->update();
|
||||
CWindowWithArtifacts::artifactRemoved(artLoc);
|
||||
}
|
||||
|
||||
void CMarketWindow::artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw)
|
||||
{
|
||||
if(!getState().has_value())
|
||||
return;
|
||||
CWindowWithArtifacts::artifactMoved(srcLoc, destLoc, withRedraw);
|
||||
assert(marketWidget);
|
||||
marketWidget->update();
|
||||
}
|
||||
|
||||
void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
auto isButtonVisible = [currentMode, market, hero](EMarketMode modeButton) -> bool
|
||||
{
|
||||
if(currentMode == modeButton)
|
||||
return false;
|
||||
|
||||
if(!market->allowsTrade(modeButton))
|
||||
return false;
|
||||
|
||||
if(modeButton == EMarketMode::RESOURCE_RESOURCE || modeButton == EMarketMode::RESOURCE_PLAYER)
|
||||
{
|
||||
if(const auto town = dynamic_cast<const CGTownInstance*>(market))
|
||||
return town->getOwner() == LOCPLINT->playerID;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return hero != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
changeModeButtons.clear();
|
||||
auto buttonPos = Point(18, 520);
|
||||
|
||||
auto addButton = [this, &buttonPos](const AnimationPath & picPath, const std::pair<std::string, std::string> & buttonHelpContainer,
|
||||
const std::function<void()> & pressButtonFunctor)
|
||||
{
|
||||
changeModeButtons.emplace_back(std::make_shared<CButton>(buttonPos, picPath, buttonHelpContainer, pressButtonFunctor));
|
||||
buttonPos -= Point(0, buttonHeightWithMargin);
|
||||
};
|
||||
|
||||
if(isButtonVisible(EMarketMode::RESOURCE_PLAYER))
|
||||
addButton(AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], std::bind(&CMarketWindow::createTransferResources, this, market, hero));
|
||||
if(isButtonVisible(EMarketMode::ARTIFACT_RESOURCE))
|
||||
addButton(AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], std::bind(&CMarketWindow::createArtifactsSelling, this, market, hero));
|
||||
if(isButtonVisible(EMarketMode::RESOURCE_ARTIFACT))
|
||||
addButton(AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], std::bind(&CMarketWindow::createArtifactsBuying, this, market, hero));
|
||||
|
||||
buttonPos = Point(516, 520 - buttonHeightWithMargin);
|
||||
if(isButtonVisible(EMarketMode::CREATURE_RESOURCE))
|
||||
addButton(AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], std::bind(&CMarketWindow::createFreelancersGuild, this, market, hero));
|
||||
if(isButtonVisible(EMarketMode::RESOURCE_RESOURCE))
|
||||
addButton(AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], std::bind(&CMarketWindow::createMarketResources, this, market, hero));
|
||||
|
||||
buttonPos = Point(516, 421);
|
||||
if(isButtonVisible(EMarketMode::CREATURE_EXP))
|
||||
{
|
||||
addButton(AnimationPath::builtin("ALTSACC.DEF"), CGI->generaltexth->zelp[572], std::bind(&CMarketWindow::createAltarCreatures, this, market, hero));
|
||||
if(marketWidget->hero->getAlignment() == EAlignment::GOOD)
|
||||
changeModeButtons.back()->block(true);
|
||||
}
|
||||
if(isButtonVisible(EMarketMode::ARTIFACT_EXP))
|
||||
{
|
||||
addButton(AnimationPath::builtin("ALTART.DEF"), CGI->generaltexth->zelp[580], std::bind(&CMarketWindow::createAltarArtifacts, this, market, hero));
|
||||
if(marketWidget->hero->getAlignment() == EAlignment::EVIL)
|
||||
changeModeButtons.back()->block(true);
|
||||
}
|
||||
}
|
||||
|
||||
void CMarketWindow::initWidgetInternals(const EMarketMode mode, const std::pair<std::string, std::string> & quitButtonHelpContainer)
|
||||
{
|
||||
background->center();
|
||||
pos = background->pos;
|
||||
marketWidget->setRedrawParent(true);
|
||||
marketWidget->moveTo(pos.topLeft());
|
||||
|
||||
createChangeModeButtons(mode, marketWidget->market, marketWidget->hero);
|
||||
quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),
|
||||
quitButtonHelpContainer, [this](){close();}, EShortcut::GLOBAL_RETURN);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("TPMRKABS.bmp"), PLAYER_COLORED);
|
||||
marketWidget = std::make_shared<CArtifactsBuying>(market, hero);
|
||||
initWidgetInternals(EMarketMode::RESOURCE_ARTIFACT, CGI->generaltexth->zelp[600]);
|
||||
}
|
||||
|
||||
void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED);
|
||||
// Create image that copies part of background containing slot MISC_1 into position of slot MISC_5
|
||||
artSlotBack = std::make_shared<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 18, 339);
|
||||
auto artsSellingMarket = std::make_shared<CArtifactsSelling>(market, hero);
|
||||
artSets.clear();
|
||||
addSetAndCallbacks(artsSellingMarket->getAOHset());
|
||||
marketWidget = artsSellingMarket;
|
||||
initWidgetInternals(EMarketMode::ARTIFACT_RESOURCE, CGI->generaltexth->zelp[600]);
|
||||
}
|
||||
|
||||
void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED);
|
||||
marketWidget = std::make_shared<CMarketResources>(market, hero);
|
||||
initWidgetInternals(EMarketMode::RESOURCE_RESOURCE, CGI->generaltexth->zelp[600]);
|
||||
}
|
||||
|
||||
void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("TPMRKCRS.bmp"), PLAYER_COLORED);
|
||||
marketWidget = std::make_shared<CFreelancerGuild>(market, hero);
|
||||
initWidgetInternals(EMarketMode::CREATURE_RESOURCE, CGI->generaltexth->zelp[600]);
|
||||
}
|
||||
|
||||
void CMarketWindow::createTransferResources(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("TPMRKPTS.bmp"), PLAYER_COLORED);
|
||||
marketWidget = std::make_shared<CTransferResources>(market, hero);
|
||||
initWidgetInternals(EMarketMode::RESOURCE_PLAYER, CGI->generaltexth->zelp[600]);
|
||||
}
|
||||
|
||||
void CMarketWindow::createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("ALTRART2.bmp"), PLAYER_COLORED);
|
||||
auto altarArtifacts = std::make_shared<CAltarArtifacts>(market, hero);
|
||||
marketWidget = altarArtifacts;
|
||||
artSets.clear();
|
||||
addSetAndCallbacks(altarArtifacts->getAOHset());
|
||||
initWidgetInternals(EMarketMode::ARTIFACT_EXP, CGI->generaltexth->zelp[568]);
|
||||
updateHero();
|
||||
quitButton->addCallback([altarArtifacts](){altarArtifacts->putBackArtifacts();});
|
||||
}
|
||||
|
||||
void CMarketWindow::createAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
background = createBg(ImagePath::builtin("ALTARMON.bmp"), PLAYER_COLORED);
|
||||
marketWidget = std::make_shared<CAltarCreatures>(market, hero);
|
||||
initWidgetInternals(EMarketMode::CREATURE_EXP, CGI->generaltexth->zelp[568]);
|
||||
updateHero();
|
||||
}
|
50
client/windows/CMarketWindow.h
Normal file
50
client/windows/CMarketWindow.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* CMarketWindow.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 "../widgets/markets/CMarketBase.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "CWindowObject.h"
|
||||
|
||||
class CMarketWindow : public CStatusbarWindow, public CWindowWithArtifacts, public IGarrisonHolder
|
||||
{
|
||||
public:
|
||||
CMarketWindow(const IMarket * market, const CGHeroInstance * hero, const std::function<void()> & onWindowClosed, EMarketMode mode);
|
||||
void updateResource();
|
||||
void updateArtifacts();
|
||||
void updateGarrisons() override;
|
||||
void updateHero();
|
||||
void close() override;
|
||||
bool holdsGarrison(const CArmedInstance * army) override;
|
||||
void artifactRemoved(const ArtifactLocation & artLoc) override;
|
||||
void artifactMoved(const ArtifactLocation & srcLoc, const ArtifactLocation & destLoc, bool withRedraw) override;
|
||||
|
||||
private:
|
||||
void createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero);
|
||||
void initWidgetInternals(const EMarketMode mode, const std::pair<std::string, std::string> & quitButtonHelpContainer);
|
||||
|
||||
void createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createMarketResources(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createTransferResources(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createAltarArtifacts(const IMarket * market, const CGHeroInstance * hero);
|
||||
void createAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
||||
|
||||
const int buttonHeightWithMargin = 32 + 3;
|
||||
std::vector<std::shared_ptr<CButton>> changeModeButtons;
|
||||
std::shared_ptr<CButton> quitButton;
|
||||
std::function<void()> windowClosedCallback;
|
||||
const Point quitButtonPos = Point(516, 520);
|
||||
std::shared_ptr<CMarketBase> marketWidget;
|
||||
|
||||
// This is workaround for bug in H3 files where this slot for ragdoll on this screen is missing
|
||||
std::shared_ptr<CPicture> artSlotBack;
|
||||
};
|
@ -1,679 +0,0 @@
|
||||
/*
|
||||
* CTradeWindow.cpp, 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
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CTradeWindow.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
#include "../render/Canvas.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../widgets/Buttons.h"
|
||||
#include "../widgets/Slider.h"
|
||||
#include "../widgets/TextControls.h"
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
#include "../../lib/CHeroHandler.h"
|
||||
#include "../../lib/mapObjects/CGHeroInstance.h"
|
||||
#include "../../lib/mapObjects/CGTownInstance.h"
|
||||
#include "../../lib/mapObjects/CGMarket.h"
|
||||
|
||||
CTradeWindow::CTradeWindow(const ImagePath & bgName, const IMarket *Market, const CGHeroInstance *Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode):
|
||||
CTradeBase(Market, Hero),
|
||||
CWindowObject(PLAYER_COLORED, bgName),
|
||||
onWindowClosed(onWindowClosed),
|
||||
readyToTrade(false)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
mode = Mode;
|
||||
initTypes();
|
||||
}
|
||||
|
||||
void CTradeWindow::initTypes()
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
itemsType[1] = EType::RESOURCE;
|
||||
itemsType[0] = EType::RESOURCE;
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
itemsType[1] = EType::RESOURCE;
|
||||
itemsType[0] = EType::PLAYER;
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
itemsType[1] = EType::CREATURE;
|
||||
itemsType[0] = EType::RESOURCE;
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
itemsType[1] = EType::RESOURCE;
|
||||
itemsType[0] = EType::ARTIFACT_TYPE;
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
itemsType[1] = EType::ARTIFACT_INSTANCE;
|
||||
itemsType[0] = EType::RESOURCE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeWindow::initItems(bool Left)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||
|
||||
if(Left && (itemsType[1] == EType::ARTIFACT_TYPE || itemsType[1] == EType::ARTIFACT_INSTANCE))
|
||||
{
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
{
|
||||
auto item = std::make_shared<CTradeableItem>(Rect(Point(137, 469), Point()), itemsType[Left], -1, 1, 0);
|
||||
item->recActions &= ~(UPDATE | SHOWALL);
|
||||
items[Left].push_back(item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto updRightSub = [this](EMarketMode marketMode)
|
||||
{
|
||||
if(hLeft)
|
||||
for(const auto & slot : rightTradePanel->slots)
|
||||
{
|
||||
int h1, h2; //hlp variables for getting offer
|
||||
market->getOffer(hLeft->id, slot->id, h1, h2, marketMode);
|
||||
|
||||
rightTradePanel->updateOffer(*slot, h1, h2);
|
||||
}
|
||||
else
|
||||
rightTradePanel->clearSubtitles();
|
||||
};
|
||||
|
||||
auto clickPressedTradePanel = [this](const std::shared_ptr<CTradeableItem> & newSlot, bool left)
|
||||
{
|
||||
CTradeBase::onSlotClickPressed(newSlot, left ? hLeft : hRight);
|
||||
selectionChanged(left);
|
||||
};
|
||||
|
||||
if(Left && mode == EMarketMode::CREATURE_RESOURCE)
|
||||
{
|
||||
CreaturesPanel::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<CreaturesPanel>(std::bind(clickPressedTradePanel, _1, true), slots);
|
||||
leftTradePanel->moveBy(Point(45, 123));
|
||||
leftTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
|
||||
{
|
||||
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<ResourcesPanel>(
|
||||
[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
|
||||
{
|
||||
clickPressedTradePanel(newSlot, true);
|
||||
},
|
||||
[this]()
|
||||
{
|
||||
for(const auto & slot : leftTradePanel->slots)
|
||||
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
|
||||
});
|
||||
leftTradePanel->moveBy(Point(39, 182));
|
||||
leftTradePanel->updateSlots();
|
||||
}
|
||||
else if(!Left && mode == EMarketMode::RESOURCE_RESOURCE)
|
||||
{
|
||||
rightTradePanel = std::make_shared<ResourcesPanel>(
|
||||
[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
|
||||
{
|
||||
clickPressedTradePanel(newSlot, false);
|
||||
},
|
||||
[this, updRightSub]()
|
||||
{
|
||||
updRightSub(EMarketMode::RESOURCE_RESOURCE);
|
||||
if(hLeft)
|
||||
rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
|
||||
});
|
||||
rightTradePanel->moveBy(Point(327, 181));
|
||||
}
|
||||
else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::CREATURE_RESOURCE))
|
||||
{
|
||||
rightTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
|
||||
std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
|
||||
rightTradePanel->moveBy(Point(327, 181));
|
||||
}
|
||||
else if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||
{
|
||||
rightTradePanel = std::make_shared<ArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
|
||||
std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
|
||||
rightTradePanel->moveBy(Point(327, 181));
|
||||
rightTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
|
||||
{
|
||||
return vstd::contains(market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
|
||||
};
|
||||
}
|
||||
else if(!Left && mode == EMarketMode::RESOURCE_PLAYER)
|
||||
{
|
||||
rightTradePanel = std::make_shared<PlayersPanel>(std::bind(clickPressedTradePanel, _1, false));
|
||||
rightTradePanel->moveBy(Point(333, 83));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeWindow::initSubs(bool Left)
|
||||
{
|
||||
if(itemsType[Left] == EType::RESOURCE || itemsType[Left] == EType::ARTIFACT_TYPE)
|
||||
{
|
||||
if(Left)
|
||||
leftTradePanel->updateSlots();
|
||||
else
|
||||
rightTradePanel->updateSlots();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeWindow::showAll(Canvas & to)
|
||||
{
|
||||
CWindowObject::showAll(to);
|
||||
|
||||
if(readyToTrade)
|
||||
{
|
||||
if(hLeft)
|
||||
hLeft->showAllAt(pos.topLeft() + selectionOffset(true), updateSlotSubtitle(true), to);
|
||||
if(hRight)
|
||||
hRight->showAllAt(pos.topLeft() + selectionOffset(false), updateSlotSubtitle(false), to);
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeWindow::close()
|
||||
{
|
||||
if (onWindowClosed)
|
||||
onWindowClosed();
|
||||
|
||||
CWindowObject::close();
|
||||
}
|
||||
|
||||
void CTradeWindow::setMode(EMarketMode Mode)
|
||||
{
|
||||
const IMarket *m = market;
|
||||
const CGHeroInstance *h = hero;
|
||||
const auto functor = onWindowClosed;
|
||||
|
||||
onWindowClosed = nullptr; // don't call on closing of this window - pass it to next window
|
||||
close();
|
||||
|
||||
switch(Mode)
|
||||
{
|
||||
case EMarketMode::CREATURE_EXP:
|
||||
case EMarketMode::ARTIFACT_EXP:
|
||||
break;
|
||||
default:
|
||||
GH.windows().createAndPushWindow<CMarketplaceWindow>(m, h, functor, Mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CTradeWindow::artifactSelected(CArtPlace * slot)
|
||||
{
|
||||
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
|
||||
items[1][0]->setArtInstance(slot->getArt());
|
||||
if(slot->getArt())
|
||||
hLeft = items[1][0];
|
||||
else
|
||||
hLeft = nullptr;
|
||||
|
||||
selectionChanged(true);
|
||||
}
|
||||
|
||||
ImagePath CMarketplaceWindow::getBackgroundForMode(EMarketMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
return ImagePath::builtin("TPMRKRES.bmp");
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
return ImagePath::builtin("TPMRKPTS.bmp");
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
return ImagePath::builtin("TPMRKCRS.bmp");
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
return ImagePath::builtin("TPMRKABS.bmp");
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
return ImagePath::builtin("TPMRKASS.bmp");
|
||||
}
|
||||
assert(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode)
|
||||
: CTradeWindow(getBackgroundForMode(Mode), Market, Hero, onWindowClosed, Mode)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
|
||||
madeTransaction = false;
|
||||
bool sliderNeeded = (mode != EMarketMode::RESOURCE_ARTIFACT && mode != EMarketMode::ARTIFACT_RESOURCE);
|
||||
|
||||
statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
|
||||
|
||||
std::string title;
|
||||
|
||||
if(auto * o = dynamic_cast<const CGTownInstance *>(market))
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
title = (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated();
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
|
||||
|
||||
// create image that copies part of background containing slot MISC_1 into position of slot MISC_5
|
||||
// this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing
|
||||
images.push_back(std::make_shared<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 18, 339 ));
|
||||
break;
|
||||
default:
|
||||
title = CGI->generaltexth->allTexts[158];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(auto * o = dynamic_cast<const CGMarket *>(market))
|
||||
{
|
||||
title = o->title;
|
||||
}
|
||||
|
||||
titleLabel = std::make_shared<CLabel>(300, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title);
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
{
|
||||
arts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
|
||||
arts->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
|
||||
arts->setHero(hero);
|
||||
addSetAndCallbacks(arts);
|
||||
}
|
||||
initItems(false);
|
||||
initItems(true);
|
||||
|
||||
ok = std::make_shared<CButton>(Point(516, 520), AnimationPath::builtin("IOK6432.DEF"), CGI->generaltexth->zelp[600], [&](){ close(); }, EShortcut::GLOBAL_RETURN);
|
||||
deal = std::make_shared<CButton>(Point(307, 520), AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [&](){ makeDeal(); } );
|
||||
deal->block(true);
|
||||
|
||||
if(sliderNeeded)
|
||||
{
|
||||
slider = std::make_shared<CSlider>(Point(231, 490), 137, std::bind(&CMarketplaceWindow::sliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL);
|
||||
max = std::make_shared<CButton>(Point(229, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], [&](){ setMax(); });
|
||||
max->block(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
deal->moveBy(Point(-30, 0));
|
||||
}
|
||||
|
||||
//left side
|
||||
switch(Mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
labels.push_back(std::make_shared<CLabel>(154, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
//%s's Creatures
|
||||
labels.push_back(std::make_shared<CLabel>(152, 102, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
//%s's Artifacts
|
||||
labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
|
||||
break;
|
||||
}
|
||||
|
||||
Rect traderTextRect;
|
||||
|
||||
//right side
|
||||
switch(Mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
labels.push_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
|
||||
traderTextRect = Rect(316, 48, 260, 75);
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
labels.push_back(std::make_shared<CLabel>(445, 55, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
|
||||
traderTextRect = Rect(28, 48, 260, 75);
|
||||
break;
|
||||
}
|
||||
|
||||
traderText = std::make_shared<CTextBox>("", traderTextRect, 0, FONT_SMALL, ETextAlignment::CENTER);
|
||||
int specialOffset = mode == EMarketMode::ARTIFACT_RESOURCE ? 35 : 0; //in selling artifacts mode we need to move res-res and art-res buttons down
|
||||
|
||||
if(printButtonFor(EMarketMode::RESOURCE_PLAYER))
|
||||
buttons.push_back(std::make_shared<CButton>(Point(18, 520),AnimationPath::builtin("TPMRKBU1.DEF"), CGI->generaltexth->zelp[612], [&](){ setMode(EMarketMode::RESOURCE_PLAYER);}));
|
||||
if(printButtonFor(EMarketMode::RESOURCE_RESOURCE))
|
||||
buttons.push_back(std::make_shared<CButton>(Point(516, 450 + specialOffset),AnimationPath::builtin("TPMRKBU5.DEF"), CGI->generaltexth->zelp[605], [&](){ setMode(EMarketMode::RESOURCE_RESOURCE);}));
|
||||
if(printButtonFor(EMarketMode::CREATURE_RESOURCE))
|
||||
buttons.push_back(std::make_shared<CButton>(Point(516, 485),AnimationPath::builtin("TPMRKBU4.DEF"), CGI->generaltexth->zelp[599], [&](){ setMode(EMarketMode::CREATURE_RESOURCE);}));
|
||||
if(printButtonFor(EMarketMode::RESOURCE_ARTIFACT))
|
||||
buttons.push_back(std::make_shared<CButton>(Point(18, 450 + specialOffset),AnimationPath::builtin("TPMRKBU2.DEF"), CGI->generaltexth->zelp[598], [&](){ setMode(EMarketMode::RESOURCE_ARTIFACT);}));
|
||||
if(printButtonFor(EMarketMode::ARTIFACT_RESOURCE))
|
||||
buttons.push_back(std::make_shared<CButton>(Point(18, 485),AnimationPath::builtin("TPMRKBU3.DEF"), CGI->generaltexth->zelp[613], [&](){ setMode(EMarketMode::ARTIFACT_RESOURCE);}));
|
||||
|
||||
updateTraderText();
|
||||
}
|
||||
|
||||
CMarketplaceWindow::~CMarketplaceWindow() = default;
|
||||
|
||||
void CMarketplaceWindow::setMax()
|
||||
{
|
||||
slider->scrollToMax();
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::makeDeal()
|
||||
{
|
||||
int sliderValue = 0;
|
||||
if(slider)
|
||||
sliderValue = slider->getValue();
|
||||
else
|
||||
sliderValue = !deal->isBlocked(); //should always be 1
|
||||
|
||||
if(!sliderValue)
|
||||
return;
|
||||
|
||||
bool allowDeal = true;
|
||||
int leftIdToSend = hLeft->id;
|
||||
switch (mode)
|
||||
{
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
leftIdToSend = hLeft->serial;
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
leftIdToSend = hLeft->getArtInstance()->getId().getNum();
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
if(!ArtifactID(hRight->id).toArtifact()->canBePutAt(hero))
|
||||
{
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("core.genrltxt.326"));
|
||||
allowDeal = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(allowDeal)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, SlotID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), PlayerColor(hRight->id), slider->getValue() * r1, hero);
|
||||
slider->scrollTo(0);
|
||||
break;
|
||||
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), ArtifactID(hRight->id), r2, hero);
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
LOCPLINT->cb->trade(market, mode, ArtifactInstanceID(leftIdToSend), GameResID(hRight->id), r2, hero);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
madeTransaction = true;
|
||||
hLeft = nullptr;
|
||||
hRight = nullptr;
|
||||
if(leftTradePanel)
|
||||
leftTradePanel->deselect();
|
||||
assert(rightTradePanel);
|
||||
rightTradePanel->deselect();
|
||||
selectionChanged(true);
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::sliderMoved( int to )
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::selectionChanged(bool side)
|
||||
{
|
||||
readyToTrade = hLeft && hRight;
|
||||
if(mode == EMarketMode::RESOURCE_RESOURCE)
|
||||
readyToTrade = readyToTrade && (hLeft->id != hRight->id); //for resource trade, two DIFFERENT resources must be selected
|
||||
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE && !hLeft)
|
||||
arts->unmarkSlots();
|
||||
|
||||
if(readyToTrade)
|
||||
{
|
||||
int soldItemId = hLeft->id;
|
||||
market->getOffer(soldItemId, hRight->id, r1, r2, mode);
|
||||
|
||||
if(slider)
|
||||
{
|
||||
int newAmount = -1;
|
||||
if(itemsType[1] == EType::RESOURCE)
|
||||
newAmount = LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(soldItemId));
|
||||
else if(itemsType[1] == EType::CREATURE)
|
||||
newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack());
|
||||
else
|
||||
assert(0);
|
||||
|
||||
slider->setAmount(newAmount / r1);
|
||||
slider->scrollTo(0);
|
||||
max->block(false);
|
||||
deal->block(false);
|
||||
}
|
||||
else if(itemsType[1] == EType::RESOURCE) //buying -> check if we can afford transaction
|
||||
{
|
||||
deal->block(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(soldItemId)) < r1);
|
||||
}
|
||||
else
|
||||
deal->block(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(slider)
|
||||
{
|
||||
max->block(true);
|
||||
slider->setAmount(0);
|
||||
slider->scrollTo(0);
|
||||
}
|
||||
deal->block(true);
|
||||
}
|
||||
|
||||
if(side && itemsType[0] != EType::PLAYER) //items[1] selection changed, recalculate offers
|
||||
initSubs(false);
|
||||
|
||||
updateTraderText();
|
||||
redraw();
|
||||
}
|
||||
|
||||
bool CMarketplaceWindow::printButtonFor(EMarketMode M) const
|
||||
{
|
||||
if (!market->allowsTrade(M))
|
||||
return false;
|
||||
|
||||
if (M == mode)
|
||||
return false;
|
||||
|
||||
if ( M == EMarketMode::RESOURCE_RESOURCE || M == EMarketMode::RESOURCE_PLAYER)
|
||||
{
|
||||
auto * town = dynamic_cast<const CGTownInstance *>(market);
|
||||
|
||||
if (town)
|
||||
return town->getOwner() == LOCPLINT->playerID;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return hero != nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::updateGarrison()
|
||||
{
|
||||
if(mode != EMarketMode::CREATURE_RESOURCE)
|
||||
return;
|
||||
|
||||
leftTradePanel->deleteSlots();
|
||||
leftTradePanel->updateSlots();
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::artifactsChanged(bool Left)
|
||||
{
|
||||
assert(!Left);
|
||||
if(mode != EMarketMode::RESOURCE_ARTIFACT)
|
||||
return;
|
||||
|
||||
rightTradePanel->deleteSlots();
|
||||
redraw();
|
||||
}
|
||||
|
||||
std::string CMarketplaceWindow::updateSlotSubtitle(bool Left) const
|
||||
{
|
||||
if(Left)
|
||||
{
|
||||
switch(itemsType[1])
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
case EType::CREATURE:
|
||||
{
|
||||
int val = slider
|
||||
? slider->getValue() * r1
|
||||
: (((deal->isBlocked())) ? 0 : r1);
|
||||
|
||||
return std::to_string(val);
|
||||
}
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
return ((deal->isBlocked()) ? "0" : "1");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(itemsType[0])
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
if(slider)
|
||||
return std::to_string( slider->getValue() * r2 );
|
||||
else
|
||||
return std::to_string(r2);
|
||||
case EType::ARTIFACT_TYPE:
|
||||
return ((deal->isBlocked()) ? "0" : "1");
|
||||
case EType::PLAYER:
|
||||
return (hRight ? CGI->generaltexth->capColors[hRight->id] : "");
|
||||
}
|
||||
}
|
||||
|
||||
return "???";
|
||||
}
|
||||
|
||||
Point CMarketplaceWindow::selectionOffset(bool Left) const
|
||||
{
|
||||
if(Left)
|
||||
{
|
||||
switch(itemsType[1])
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
return Point(122, 448);
|
||||
case EType::CREATURE:
|
||||
return Point(128, 450);
|
||||
case EType::ARTIFACT_INSTANCE:
|
||||
return Point(134, 469);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(itemsType[0])
|
||||
{
|
||||
case EType::RESOURCE:
|
||||
if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
return Point(410, 471);
|
||||
else
|
||||
return Point(410, 448);
|
||||
case EType::ARTIFACT_TYPE:
|
||||
return Point(411, 449);
|
||||
case EType::PLAYER:
|
||||
return Point(417, 451);
|
||||
}
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return Point(0,0);
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::resourceChanged()
|
||||
{
|
||||
initSubs(true);
|
||||
}
|
||||
|
||||
void CMarketplaceWindow::updateTraderText()
|
||||
{
|
||||
if(readyToTrade)
|
||||
{
|
||||
if(mode == EMarketMode::RESOURCE_PLAYER)
|
||||
{
|
||||
//I can give %s to the %s player.
|
||||
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[165]) % hLeft->getName() % hRight->getName()));
|
||||
}
|
||||
else if(mode == EMarketMode::RESOURCE_ARTIFACT)
|
||||
{
|
||||
//I can offer you the %s for %d %s of %s.
|
||||
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[267]) % hRight->getName() % r1 % CGI->generaltexth->allTexts[160 + (r1==1)] % hLeft->getName()));
|
||||
}
|
||||
else if(mode == EMarketMode::RESOURCE_RESOURCE)
|
||||
{
|
||||
//I can offer you %d %s of %s for %d %s of %s.
|
||||
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[157]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % r1 % CGI->generaltexth->allTexts[160 + (r1==1)] % hLeft->getName()));
|
||||
}
|
||||
else if(mode == EMarketMode::CREATURE_RESOURCE)
|
||||
{
|
||||
//I can offer you %d %s of %s for %d %s.
|
||||
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[269]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % r1 % hLeft->getName(r1)));
|
||||
}
|
||||
else if(mode == EMarketMode::ARTIFACT_RESOURCE)
|
||||
{
|
||||
//I can offer you %d %s of %s for your %s.
|
||||
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[268]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % hLeft->getName(r1)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int gnrtxtnr = -1;
|
||||
if(madeTransaction)
|
||||
{
|
||||
if(mode == EMarketMode::RESOURCE_PLAYER)
|
||||
gnrtxtnr = 166; //Are there any other resources you'd like to give away?
|
||||
else
|
||||
gnrtxtnr = 162; //You have received quite a bargain. I expect to make no profit on the deal. Can I interest you in any of my other wares?
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mode == EMarketMode::RESOURCE_PLAYER)
|
||||
gnrtxtnr = 167; //If you'd like to give any of your resources to another player, click on the item you wish to give and to whom.
|
||||
else
|
||||
gnrtxtnr = 163; //Please inspect our fine wares. If you feel like offering a trade, click on the items you wish to trade with and for.
|
||||
}
|
||||
traderText->setText(CGI->generaltexth->allTexts[gnrtxtnr]);
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* CTradeWindow.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 "../widgets/markets/CTradeBase.h"
|
||||
#include "../widgets/CWindowWithArtifacts.h"
|
||||
#include "CWindowObject.h"
|
||||
|
||||
class CSlider;
|
||||
class CGStatusBar;
|
||||
|
||||
class CTradeWindow : public CTradeBase, public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
|
||||
{
|
||||
public:
|
||||
EType itemsType[2];
|
||||
|
||||
EMarketMode mode;
|
||||
std::shared_ptr<CButton> ok;
|
||||
std::shared_ptr<CButton> max;
|
||||
|
||||
std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
|
||||
bool readyToTrade;
|
||||
|
||||
CTradeWindow(const ImagePath & bgName, const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode); //c
|
||||
|
||||
void showAll(Canvas & to) override;
|
||||
void close() override;
|
||||
|
||||
void initSubs(bool Left);
|
||||
void initTypes();
|
||||
void initItems(bool Left);
|
||||
void setMode(EMarketMode Mode); //mode setter
|
||||
|
||||
void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot
|
||||
virtual void selectionChanged(bool side) = 0; //true == left
|
||||
virtual Point selectionOffset(bool Left) const = 0;
|
||||
virtual std::string updateSlotSubtitle(bool Left) const = 0;
|
||||
virtual void updateGarrison() = 0;
|
||||
virtual void artifactsChanged(bool left) = 0;
|
||||
protected:
|
||||
std::function<void()> onWindowClosed;
|
||||
std::shared_ptr<CGStatusBar> statusBar;
|
||||
std::vector<std::shared_ptr<CPicture>> images;
|
||||
};
|
||||
|
||||
class CMarketplaceWindow : public CTradeWindow
|
||||
{
|
||||
std::shared_ptr<CLabel> titleLabel;
|
||||
std::shared_ptr<CArtifactsOfHeroMarket> arts;
|
||||
|
||||
bool printButtonFor(EMarketMode M) const;
|
||||
|
||||
ImagePath getBackgroundForMode(EMarketMode mode);
|
||||
public:
|
||||
int r1, r2; //suggested amounts of traded resources
|
||||
bool madeTransaction; //if player made at least one transaction
|
||||
std::shared_ptr<CTextBox> traderText;
|
||||
|
||||
void setMax();
|
||||
void sliderMoved(int to);
|
||||
void makeDeal() override;
|
||||
void selectionChanged(bool side) override; //true == left
|
||||
CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode);
|
||||
~CMarketplaceWindow();
|
||||
|
||||
Point selectionOffset(bool Left) const override;
|
||||
std::string updateSlotSubtitle(bool Left) const override;
|
||||
|
||||
void updateGarrison() override; //removes creatures with count 0 from the list (apparently whole stack has been sold)
|
||||
void artifactsChanged(bool left) override;
|
||||
void resourceChanged();
|
||||
void updateTraderText();
|
||||
};
|
Loading…
Reference in New Issue
Block a user