From 1f6e0fae7db83cbad0a5183abb9754cdc0443fcd Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 03:27:28 +0200 Subject: [PATCH 01/22] quickspell draft --- client/battle/BattleInterfaceClasses.cpp | 49 ++++++++++++++++++++++++ client/battle/BattleInterfaceClasses.h | 17 ++++++++ client/battle/BattleWindow.cpp | 24 ++++++++++++ client/battle/BattleWindow.h | 2 + client/widgets/Buttons.cpp | 19 ++++++++- client/widgets/Buttons.h | 5 +++ 6 files changed, 115 insertions(+), 1 deletion(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index d6e2ca161..0dc794d5b 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -417,6 +417,55 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her addUsedEvents(TIME); } +QuickSpellPanel::QuickSpellPanel() + : CIntObject(LCLICK | SHOW_POPUP) +{ + OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + + setEnabled(false); + + pos = Rect(0, 0, 52, 372); + background = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); + rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); + + for(int i = 0; i < 10; i++) { + SpellID id = 14; + auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }, EShortcut::HERO_COSTUME_0); + button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), i > 0 ? id.num : 0)); + + if(i > 3) + { + button->block(true); + buttonsDisabled.push_back(std::make_shared(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); + } + + buttons.push_back(button); + } +} + +void QuickSpellPanel::show(Canvas & to) +{ + showAll(to); + CIntObject::show(to); +} + +void QuickSpellPanel::clickReleased(const Point & cursorPosition) +{ + if(!pos.isInside(cursorPosition)) + setEnabled(false); +} + +void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) +{ + if(!pos.isInside(cursorPosition)) + setEnabled(false); +} + +bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const +{ + return true; // capture click also outside of window +} + HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground) : CIntObject(0) { diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index c385db754..c62f7279c 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -147,6 +147,23 @@ public: BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender); }; +class QuickSpellPanel : public CIntObject +{ +private: + std::shared_ptr background; + std::shared_ptr rect; + std::vector> buttons; + std::vector> buttonsDisabled; + + bool receiveEvent(const Point & position, int eventType) const override; + void clickReleased(const Point & cursorPosition) override; + void showPopupWindow(const Point & cursorPosition) override; +public: + QuickSpellPanel(); + + void show(Canvas & to) override; +}; + class HeroInfoBasicPanel : public CIntObject //extracted from InfoWindow to fit better as non-popup embed element { private: diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index c1a21e044..0b8cddb5e 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -98,6 +98,30 @@ BattleWindow::BattleWindow(BattleInterface & owner): createStickyHeroInfoWindows(); createTimerInfoWindows(); + auto w = widget("cast"); + if(w) + { + auto hero = owner.getBattle()->battleGetMyHero(); + if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) + { + quickSpellPanelWindow = std::make_shared(); + quickSpellPanelWindow->moveTo(Point(w->pos.x - 2, w->pos.y - 378)); + w->addHoverCallback([this, w](bool on) + { + if(on) + quickSpellPanelWindow->setEnabled(true); + else + if(GH.getCursorPosition().x <= w->pos.x || GH.getCursorPosition().x >= w->pos.x + w->pos.w || GH.getCursorPosition().y >= w->pos.y + w->pos.h) + quickSpellPanelWindow->setEnabled(false); + }); + w->addPanningCallback([this](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) + { + if((currentPosition - initialPosition).y < -20) + quickSpellPanelWindow->setEnabled(true); + }); + } + } + if ( owner.tacticsMode ) tacticPhaseStarted(); else diff --git a/client/battle/BattleWindow.h b/client/battle/BattleWindow.h index 5369cca9d..39a714635 100644 --- a/client/battle/BattleWindow.h +++ b/client/battle/BattleWindow.h @@ -27,6 +27,7 @@ class StackQueue; class TurnTimerWidget; class HeroInfoBasicPanel; class StackInfoBasicPanel; +class QuickSpellPanel; /// GUI object that handles functionality of panel at the bottom of combat screen class BattleWindow : public InterfaceObjectConfigurable @@ -39,6 +40,7 @@ class BattleWindow : public InterfaceObjectConfigurable std::shared_ptr defenderHeroWindow; std::shared_ptr attackerStackWindow; std::shared_ptr defenderStackWindow; + std::shared_ptr quickSpellPanelWindow; std::shared_ptr attackerTimerWidget; std::shared_ptr defenderTimerWidget; diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 620c08587..dfa6adc12 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -67,6 +67,16 @@ void CButton::addCallback(const std::function & callback) this->callback += callback; } +void CButton::addHoverCallback(const std::function & callback) +{ + this->hoverCallback += callback; +} + +void CButton::addPanningCallback(const std::function & callback) +{ + this->panningCallback += callback; +} + void ButtonBase::setTextOverlay(const std::string & Text, EFonts font, ColorRGBA color) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); @@ -295,6 +305,8 @@ void CButton::showPopupWindow(const Point & cursorPosition) void CButton::hover (bool on) { + hoverCallback(on); + if(hoverable && !isBlocked()) { if(on) @@ -319,6 +331,11 @@ void CButton::hover (bool on) } } +void CButton::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) +{ + panningCallback(initialPosition, currentPosition, lastUpdateDistance); +} + ButtonBase::ButtonBase(Point position, const AnimationPath & defName, EShortcut key, bool playerColoredButton) : CKeyShortcut(key) , stateToIndex({0, 1, 2, 3}) @@ -351,7 +368,7 @@ CButton::CButton(Point position, const AnimationPath &defName, const std::pair callback; + CFunctionList hoverCallback; + CFunctionList panningCallback; std::array hoverTexts; //texts for statusbar, if empty - first entry will be used std::optional borderColor; // mapping of button state to border color @@ -90,6 +92,8 @@ public: /// adds one more callback to on-click actions void addCallback(const std::function & callback); + void addHoverCallback(const std::function & callback); + void addPanningCallback(const std::function & callback); void addHoverText(EButtonState state, const std::string & text); @@ -114,6 +118,7 @@ public: void clickReleased(const Point & cursorPosition) override; void clickCancel(const Point & cursorPosition) override; void hover (bool on) override; + void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void showAll(Canvas & to) override; /// generates tooltip that can be passed into constructor From 814241e8366ac7f528aeda39428343776a4bb724 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 04:23:53 +0200 Subject: [PATCH 02/22] converted to window --- client/battle/BattleInterfaceClasses.cpp | 30 ++++++++++++++++++++---- client/battle/BattleInterfaceClasses.h | 7 ++++-- client/battle/BattleWindow.cpp | 9 +++---- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 0dc794d5b..f34f3091e 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -417,11 +417,13 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her addUsedEvents(TIME); } -QuickSpellPanel::QuickSpellPanel() - : CIntObject(LCLICK | SHOW_POPUP) +QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget) + : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + addUsedEvents(LCLICK | SHOW_POPUP | MOVE); + setEnabled(false); pos = Rect(0, 0, 52, 372); @@ -452,13 +454,33 @@ void QuickSpellPanel::show(Canvas & to) void QuickSpellPanel::clickReleased(const Point & cursorPosition) { if(!pos.isInside(cursorPosition)) - setEnabled(false); + close(); + + if(initWidget->pos.isInside(cursorPosition)) + { + initWidget->clickPressed(cursorPosition); + initWidget->clickReleased(cursorPosition); + } } void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) { if(!pos.isInside(cursorPosition)) - setEnabled(false); + close(); + + if(initWidget->pos.isInside(cursorPosition)) + { + initWidget->showPopupWindow(cursorPosition); + } +} + +void QuickSpellPanel::mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) +{ + if( cursorPosition.x <= initWidget->pos.x - 20 || + cursorPosition.x >= initWidget->pos.x + initWidget->pos.w + 20 || + cursorPosition.y <= initWidget->pos.y - pos.h - 20 || + (cursorPosition.y >= initWidget->pos.y && !initWidget->pos.isInside(cursorPosition))) + close(); } bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index c62f7279c..d5c8ceff1 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -147,7 +147,7 @@ public: BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender); }; -class QuickSpellPanel : public CIntObject +class QuickSpellPanel : public CWindowObject { private: std::shared_ptr background; @@ -158,8 +158,11 @@ private: bool receiveEvent(const Point & position, int eventType) const override; void clickReleased(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override; + void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override; + + std::shared_ptr initWidget; public: - QuickSpellPanel(); + QuickSpellPanel(std::shared_ptr initWidget); void show(Canvas & to) override; }; diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 0b8cddb5e..a2dc2bdc2 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -104,20 +104,17 @@ BattleWindow::BattleWindow(BattleInterface & owner): auto hero = owner.getBattle()->battleGetMyHero(); if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) { - quickSpellPanelWindow = std::make_shared(); + quickSpellPanelWindow = std::make_shared(w); quickSpellPanelWindow->moveTo(Point(w->pos.x - 2, w->pos.y - 378)); w->addHoverCallback([this, w](bool on) { if(on) - quickSpellPanelWindow->setEnabled(true); - else - if(GH.getCursorPosition().x <= w->pos.x || GH.getCursorPosition().x >= w->pos.x + w->pos.w || GH.getCursorPosition().y >= w->pos.y + w->pos.h) - quickSpellPanelWindow->setEnabled(false); + GH.windows().pushWindow(quickSpellPanelWindow); }); w->addPanningCallback([this](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { if((currentPosition - initialPosition).y < -20) - quickSpellPanelWindow->setEnabled(true); + GH.windows().pushWindow(quickSpellPanelWindow); }); } } From 989394de538a5ddd97743174a6e433c366ea6114 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 20:45:55 +0200 Subject: [PATCH 03/22] Selectionwindow --- client/battle/BattleInterfaceClasses.cpp | 48 ++++++++++++++++++++---- client/battle/BattleInterfaceClasses.h | 14 +++++++ client/battle/BattleWindow.cpp | 16 +++++--- client/battle/BattleWindow.h | 1 - client/widgets/Buttons.cpp | 7 ++++ client/widgets/Buttons.h | 2 + 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index f34f3091e..6bd8f6b3e 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -424,22 +424,26 @@ QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget) addUsedEvents(LCLICK | SHOW_POPUP | MOVE); - setEnabled(false); - pos = Rect(0, 0, 52, 372); background = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); + panelSelect = std::make_shared(); + for(int i = 0; i < 10; i++) { SpellID id = 14; - auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }, EShortcut::HERO_COSTUME_0); + auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), i > 0 ? id.num : 0)); + button->addPopupCallback([this](){ + panelSelect->setEnabled(true); + }); if(i > 3) { button->block(true); buttonsDisabled.push_back(std::make_shared(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); } + labels.push_back(std::make_shared(7, 4 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); buttons.push_back(button); } @@ -453,7 +457,7 @@ void QuickSpellPanel::show(Canvas & to) void QuickSpellPanel::clickReleased(const Point & cursorPosition) { - if(!pos.isInside(cursorPosition)) + if(!pos.isInside(cursorPosition) && (!panelSelect->isActive() || !panelSelect->pos.isInside(cursorPosition))) close(); if(initWidget->pos.isInside(cursorPosition)) @@ -465,7 +469,7 @@ void QuickSpellPanel::clickReleased(const Point & cursorPosition) void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) { - if(!pos.isInside(cursorPosition)) + if(!pos.isInside(cursorPosition) && (!panelSelect->isActive() || !panelSelect->pos.isInside(cursorPosition))) close(); if(initWidget->pos.isInside(cursorPosition)) @@ -476,10 +480,12 @@ void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) void QuickSpellPanel::mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) { - if( cursorPosition.x <= initWidget->pos.x - 20 || + if( (cursorPosition.x <= initWidget->pos.x - 20 || cursorPosition.x >= initWidget->pos.x + initWidget->pos.w + 20 || cursorPosition.y <= initWidget->pos.y - pos.h - 20 || - (cursorPosition.y >= initWidget->pos.y && !initWidget->pos.isInside(cursorPosition))) + (cursorPosition.y >= initWidget->pos.y && !initWidget->pos.isInside(cursorPosition))) && + (!panelSelect->isActive() || !panelSelect->pos.resize(20).isInside(cursorPosition)) + ) close(); } @@ -488,6 +494,34 @@ bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const return true; // capture click also outside of window } +QuickSpellPanelSelect::QuickSpellPanelSelect() +{ + OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + + setEnabled(false); + + std::vector> spellList; + for (auto const & s : VLC->spellh->objects) + if (s->isCombat() && !s->isSpecial() && !s->isCreatureAbility()) + spellList.push_back(s); + + auto ceil = [](int x, int y){ return(x + y - 1) / y; }; + int columnsNeeded = ceil(spellList.size(), 10); + + pos = Rect(-20 - columnsNeeded * 50, 0, columnsNeeded * 50 + 2, 372); + background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); + rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); + + for(int i = 0; i < spellList.size(); i++) + { + int y = i % 10; + int x = i / 10; + auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); + button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), spellList[i]->getId().num + 1)); + buttons.push_back(button); + } +} + HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground) : CIntObject(0) { diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index d5c8ceff1..12f036d1a 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -147,6 +147,17 @@ public: BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender); }; +class QuickSpellPanelSelect : public CIntObject +{ +private: + std::shared_ptr background; + std::shared_ptr rect; + std::vector> buttons; + +public: + QuickSpellPanelSelect(); +}; + class QuickSpellPanel : public CWindowObject { private: @@ -154,6 +165,9 @@ private: std::shared_ptr rect; std::vector> buttons; std::vector> buttonsDisabled; + std::vector> labels; + + std::shared_ptr panelSelect; bool receiveEvent(const Point & position, int eventType) const override; void clickReleased(const Point & cursorPosition) override; diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index a2dc2bdc2..9bbaad0cc 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -104,17 +104,21 @@ BattleWindow::BattleWindow(BattleInterface & owner): auto hero = owner.getBattle()->battleGetMyHero(); if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) { - quickSpellPanelWindow = std::make_shared(w); - quickSpellPanelWindow->moveTo(Point(w->pos.x - 2, w->pos.y - 378)); - w->addHoverCallback([this, w](bool on) + auto createQuickSpellPanelWindow = [](std::shared_ptr widget){ + std::shared_ptr window = std::make_shared(widget); + window->moveTo(Point(widget->pos.x - 2, widget->pos.y - 378)); + GH.windows().pushWindow(window); + }; + + w->addHoverCallback([this, createQuickSpellPanelWindow, w](bool on) { if(on) - GH.windows().pushWindow(quickSpellPanelWindow); + createQuickSpellPanelWindow(w); }); - w->addPanningCallback([this](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) + w->addPanningCallback([this, createQuickSpellPanelWindow, w](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { if((currentPosition - initialPosition).y < -20) - GH.windows().pushWindow(quickSpellPanelWindow); + createQuickSpellPanelWindow(w); }); } } diff --git a/client/battle/BattleWindow.h b/client/battle/BattleWindow.h index 39a714635..27897df45 100644 --- a/client/battle/BattleWindow.h +++ b/client/battle/BattleWindow.h @@ -40,7 +40,6 @@ class BattleWindow : public InterfaceObjectConfigurable std::shared_ptr defenderHeroWindow; std::shared_ptr attackerStackWindow; std::shared_ptr defenderStackWindow; - std::shared_ptr quickSpellPanelWindow; std::shared_ptr attackerTimerWidget; std::shared_ptr defenderTimerWidget; diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index dfa6adc12..8491afe3e 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -67,6 +67,11 @@ void CButton::addCallback(const std::function & callback) this->callback += callback; } +void CButton::addPopupCallback(const std::function & callback) +{ + this->callbackPopup += callback; +} + void CButton::addHoverCallback(const std::function & callback) { this->hoverCallback += callback; @@ -299,6 +304,8 @@ void CButton::clickCancel(const Point & cursorPosition) void CButton::showPopupWindow(const Point & cursorPosition) { + callbackPopup(); + if(!helpBox.empty()) //there is no point to show window with nothing inside... CRClickPopup::createAndPush(helpBox); } diff --git a/client/widgets/Buttons.h b/client/widgets/Buttons.h index b15bf5e7b..c551cfdea 100644 --- a/client/widgets/Buttons.h +++ b/client/widgets/Buttons.h @@ -69,6 +69,7 @@ public: class CButton : public ButtonBase { CFunctionList callback; + CFunctionList callbackPopup; CFunctionList hoverCallback; CFunctionList panningCallback; @@ -92,6 +93,7 @@ public: /// adds one more callback to on-click actions void addCallback(const std::function & callback); + void addPopupCallback(const std::function & callback); void addHoverCallback(const std::function & callback); void addPanningCallback(const std::function & callback); From 1a8a14a56deab775a3cfe939b045562411dada30 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 21:29:23 +0200 Subject: [PATCH 04/22] selectable fix --- client/battle/BattleInterfaceClasses.cpp | 26 ++++++++++++++++++------ client/battle/BattleInterfaceClasses.h | 8 ++++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 6bd8f6b3e..f3bab78b5 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -428,8 +428,13 @@ QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget) background = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); - panelSelect = std::make_shared(); + panelSelect = std::make_shared(this); + create(); +} + +void QuickSpellPanel::create() +{ for(int i = 0; i < 10; i++) { SpellID id = 14; auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); @@ -457,7 +462,7 @@ void QuickSpellPanel::show(Canvas & to) void QuickSpellPanel::clickReleased(const Point & cursorPosition) { - if(!pos.isInside(cursorPosition) && (!panelSelect->isActive() || !panelSelect->pos.isInside(cursorPosition))) + if(!pos.isInside(cursorPosition) && (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.isInside(cursorPosition))) close(); if(initWidget->pos.isInside(cursorPosition)) @@ -469,7 +474,7 @@ void QuickSpellPanel::clickReleased(const Point & cursorPosition) void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) { - if(!pos.isInside(cursorPosition) && (!panelSelect->isActive() || !panelSelect->pos.isInside(cursorPosition))) + if(!pos.isInside(cursorPosition) && (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.isInside(cursorPosition))) close(); if(initWidget->pos.isInside(cursorPosition)) @@ -484,9 +489,12 @@ void QuickSpellPanel::mouseMoved(const Point & cursorPosition, const Point & las cursorPosition.x >= initWidget->pos.x + initWidget->pos.w + 20 || cursorPosition.y <= initWidget->pos.y - pos.h - 20 || (cursorPosition.y >= initWidget->pos.y && !initWidget->pos.isInside(cursorPosition))) && - (!panelSelect->isActive() || !panelSelect->pos.resize(20).isInside(cursorPosition)) + (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.resize(20).isInside(cursorPosition)) ) close(); + + if(initWidget->pos.isInside(cursorPosition)) + panelSelect->wasEnabled = false; } bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const @@ -494,7 +502,8 @@ bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const return true; // capture click also outside of window } -QuickSpellPanelSelect::QuickSpellPanelSelect() +QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) + : parent(Parent), wasEnabled(false) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -516,7 +525,12 @@ QuickSpellPanelSelect::QuickSpellPanelSelect() { int y = i % 10; int x = i / 10; - auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); + auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this](){ + setEnabled(false); + GH.windows().totalRedraw(); + wasEnabled = true; + parent->create(); + }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), spellList[i]->getId().num + 1)); buttons.push_back(button); } diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 12f036d1a..d6b14d68d 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -44,6 +44,7 @@ class TransparentFilledRectangle; class CPlayerInterface; class BattleRenderer; class VideoWidget; +class QuickSpellPanel; /// Class which shows the console at the bottom of the battle screen and manages the text of the console class BattleConsole : public CIntObject, public IStatusBar @@ -153,9 +154,10 @@ private: std::shared_ptr background; std::shared_ptr rect; std::vector> buttons; - + QuickSpellPanel * parent; public: - QuickSpellPanelSelect(); + QuickSpellPanelSelect(QuickSpellPanel * Parent); + bool wasEnabled; // was the panel opened? -> don't close window because mouse is not in area }; class QuickSpellPanel : public CWindowObject @@ -178,6 +180,8 @@ private: public: QuickSpellPanel(std::shared_ptr initWidget); + void create(); + void show(Canvas & to) override; }; From e4dfca9f3dd0ea17fb68d39c6ab73d2612fd53fe Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 22:31:35 +0200 Subject: [PATCH 05/22] disable correctly --- client/battle/BattleInterfaceClasses.cpp | 31 ++++++++++++++++++------ client/battle/BattleInterfaceClasses.h | 5 +++- client/battle/BattleWindow.cpp | 13 +++++----- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index f3bab78b5..7ae2f2c6c 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -417,8 +417,8 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her addUsedEvents(TIME); } -QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget) - : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget) +QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget, std::shared_ptr battle) + : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget), battle(battle) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -435,17 +435,29 @@ QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget) void QuickSpellPanel::create() { + OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + + labels.clear(); + buttons.clear(); + buttonsDisabled.clear(); + + auto hero = battle->battleGetMyHero(); + if(!hero) + return; + for(int i = 0; i < 10; i++) { - SpellID id = 14; + std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); + SpellID id = SpellID::decode(spellIdentifier); + auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); - button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), i > 0 ? id.num : 0)); - button->addPopupCallback([this](){ + button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), !spellIdentifier.empty() ? id.num + 1 : 0)); + button->addPopupCallback([this, i](){ + panelSelect->spellSlot = i; panelSelect->setEnabled(true); }); - if(i > 3) + if(!id.hasValue() || !id.toSpell()->canBeCast(battle.get(), spells::Mode::HERO, hero)) { - button->block(true); buttonsDisabled.push_back(std::make_shared(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); } labels.push_back(std::make_shared(7, 4 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); @@ -525,10 +537,13 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) { int y = i % 10; int x = i / 10; - auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this](){ + ConstTransitivePtr spell = spellList[i]; + auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, spell](){ setEnabled(false); GH.windows().totalRedraw(); wasEnabled = true; + Settings configID = persistentStorage.write["quickSpell"][std::to_string(spellSlot)]; + configID->String() = spell->identifier; parent->create(); }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), spellList[i]->getId().num + 1)); diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index d6b14d68d..b035d34a3 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -45,6 +45,7 @@ class CPlayerInterface; class BattleRenderer; class VideoWidget; class QuickSpellPanel; +class CPlayerBattleCallback; /// Class which shows the console at the bottom of the battle screen and manages the text of the console class BattleConsole : public CIntObject, public IStatusBar @@ -158,6 +159,7 @@ private: public: QuickSpellPanelSelect(QuickSpellPanel * Parent); bool wasEnabled; // was the panel opened? -> don't close window because mouse is not in area + int spellSlot; }; class QuickSpellPanel : public CWindowObject @@ -177,8 +179,9 @@ private: void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override; std::shared_ptr initWidget; + std::shared_ptr battle; public: - QuickSpellPanel(std::shared_ptr initWidget); + QuickSpellPanel(std::shared_ptr initWidget, std::shared_ptr battle); void create(); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 9bbaad0cc..7d80cd6f7 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -102,23 +102,24 @@ BattleWindow::BattleWindow(BattleInterface & owner): if(w) { auto hero = owner.getBattle()->battleGetMyHero(); + auto battle = owner.getBattle(); if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) { - auto createQuickSpellPanelWindow = [](std::shared_ptr widget){ - std::shared_ptr window = std::make_shared(widget); + auto createQuickSpellPanelWindow = [](std::shared_ptr widget, std::shared_ptr battle){ + std::shared_ptr window = std::make_shared(widget, battle); window->moveTo(Point(widget->pos.x - 2, widget->pos.y - 378)); GH.windows().pushWindow(window); }; - w->addHoverCallback([this, createQuickSpellPanelWindow, w](bool on) + w->addHoverCallback([this, createQuickSpellPanelWindow, w, battle](bool on) { if(on) - createQuickSpellPanelWindow(w); + createQuickSpellPanelWindow(w, battle); }); - w->addPanningCallback([this, createQuickSpellPanelWindow, w](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) + w->addPanningCallback([this, createQuickSpellPanelWindow, w, battle](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { if((currentPosition - initialPosition).y < -20) - createQuickSpellPanelWindow(w); + createQuickSpellPanelWindow(w, battle); }); } } From 53a1bf2051e9ae0f12d560c5725edf0a78a2e405 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 23:12:48 +0200 Subject: [PATCH 06/22] add spell cast --- client/battle/BattleInterfaceClasses.cpp | 16 +++++++---- client/battle/BattleInterfaceClasses.h | 4 +-- client/battle/BattleWindow.cpp | 36 ++++++++++++++++++------ client/gui/Shortcut.h | 10 +++++++ client/gui/ShortcutHandler.cpp | 10 +++++++ config/shortcutsConfig.json | 10 +++++++ 6 files changed, 70 insertions(+), 16 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 7ae2f2c6c..2ea4015f0 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -417,8 +417,8 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her addUsedEvents(TIME); } -QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget, std::shared_ptr battle) - : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget), battle(battle) +QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget, BattleInterface & owner) + : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget), owner(owner) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); @@ -441,7 +441,7 @@ void QuickSpellPanel::create() buttons.clear(); buttonsDisabled.clear(); - auto hero = battle->battleGetMyHero(); + auto hero = owner.getBattle()->battleGetMyHero(); if(!hero) return; @@ -449,14 +449,20 @@ void QuickSpellPanel::create() std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); SpellID id = SpellID::decode(spellIdentifier); - auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [&](){ std::cout << "test"; }); + auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ + if(id.hasValue() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) + { + close(); + owner.castThisSpell(id); + } + }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), !spellIdentifier.empty() ? id.num + 1 : 0)); button->addPopupCallback([this, i](){ panelSelect->spellSlot = i; panelSelect->setEnabled(true); }); - if(!id.hasValue() || !id.toSpell()->canBeCast(battle.get(), spells::Mode::HERO, hero)) + if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { buttonsDisabled.push_back(std::make_shared(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); } diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index b035d34a3..6033d983c 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -179,9 +179,9 @@ private: void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override; std::shared_ptr initWidget; - std::shared_ptr battle; + BattleInterface & owner; public: - QuickSpellPanel(std::shared_ptr initWidget, std::shared_ptr battle); + QuickSpellPanel(std::shared_ptr initWidget, BattleInterface & owner); void create(); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 7d80cd6f7..76e3ed12f 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -45,8 +45,8 @@ #include "../../lib/CPlayerState.h" #include "../windows/settings/SettingsMainWindow.h" -BattleWindow::BattleWindow(BattleInterface & owner): - owner(owner), +BattleWindow::BattleWindow(BattleInterface & Owner): + owner(Owner), defaultAction(PossiblePlayerBattleAction::INVALID) { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; @@ -64,6 +64,25 @@ BattleWindow::BattleWindow(BattleInterface & owner): const JsonNode config(JsonPath::builtin("config/widgets/BattleWindow2.json")); + auto useSpellIfPossible = [this](int slot){ + std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(slot)].String(); + SpellID id = SpellID::decode(spellIdentifier); + if(id.hasValue() && owner.getBattle()->battleGetMyHero() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, owner.getBattle()->battleGetMyHero())) + { + owner.castThisSpell(id); + } + }; + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [useSpellIfPossible](){ useSpellIfPossible(0); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [useSpellIfPossible](){ useSpellIfPossible(1); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [useSpellIfPossible](){ useSpellIfPossible(2); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_3, [useSpellIfPossible](){ useSpellIfPossible(3); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_4, [useSpellIfPossible](){ useSpellIfPossible(4); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_5, [useSpellIfPossible](){ useSpellIfPossible(5); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_6, [useSpellIfPossible](){ useSpellIfPossible(6); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [useSpellIfPossible](){ useSpellIfPossible(7); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [useSpellIfPossible](){ useSpellIfPossible(8); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [useSpellIfPossible](){ useSpellIfPossible(9); }); + addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); addShortcut(EShortcut::BATTLE_RETREAT, std::bind(&BattleWindow::bFleef, this)); @@ -102,24 +121,23 @@ BattleWindow::BattleWindow(BattleInterface & owner): if(w) { auto hero = owner.getBattle()->battleGetMyHero(); - auto battle = owner.getBattle(); if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) { - auto createQuickSpellPanelWindow = [](std::shared_ptr widget, std::shared_ptr battle){ - std::shared_ptr window = std::make_shared(widget, battle); + auto createQuickSpellPanelWindow = [](std::shared_ptr widget, BattleInterface & owner){ + std::shared_ptr window = std::make_shared(widget, owner); window->moveTo(Point(widget->pos.x - 2, widget->pos.y - 378)); GH.windows().pushWindow(window); }; - w->addHoverCallback([this, createQuickSpellPanelWindow, w, battle](bool on) + w->addHoverCallback([this, createQuickSpellPanelWindow, w](bool on) { if(on) - createQuickSpellPanelWindow(w, battle); + createQuickSpellPanelWindow(w, owner); }); - w->addPanningCallback([this, createQuickSpellPanelWindow, w, battle](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) + w->addPanningCallback([this, createQuickSpellPanelWindow, w](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) { if((currentPosition - initialPosition).y < -20) - createQuickSpellPanelWindow(w, battle); + createQuickSpellPanelWindow(w, owner); }); } } diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index ebe89e4e2..42b96ac1c 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -186,6 +186,16 @@ enum class EShortcut BATTLE_TOGGLE_HEROES_STATS, BATTLE_OPEN_ACTIVE_UNIT, BATTLE_OPEN_HOVERED_UNIT, + BATTLE_SPELL_SHORTCUT_0, + BATTLE_SPELL_SHORTCUT_1, + BATTLE_SPELL_SHORTCUT_2, + BATTLE_SPELL_SHORTCUT_3, + BATTLE_SPELL_SHORTCUT_4, + BATTLE_SPELL_SHORTCUT_5, + BATTLE_SPELL_SHORTCUT_6, + BATTLE_SPELL_SHORTCUT_7, + BATTLE_SPELL_SHORTCUT_8, + BATTLE_SPELL_SHORTCUT_9, MARKET_DEAL, MARKET_MAX_AMOUNT, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index 3a5033882..11bafc8ae 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -222,6 +222,16 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"battleTacticsNext", EShortcut::BATTLE_TACTICS_NEXT }, {"battleTacticsEnd", EShortcut::BATTLE_TACTICS_END }, {"battleSelectAction", EShortcut::BATTLE_SELECT_ACTION }, + {"battleSpellShortcut0", EShortcut::BATTLE_SPELL_SHORTCUT_0 }, + {"battleSpellShortcut1", EShortcut::BATTLE_SPELL_SHORTCUT_1 }, + {"battleSpellShortcut2", EShortcut::BATTLE_SPELL_SHORTCUT_2 }, + {"battleSpellShortcut3", EShortcut::BATTLE_SPELL_SHORTCUT_3 }, + {"battleSpellShortcut4", EShortcut::BATTLE_SPELL_SHORTCUT_4 }, + {"battleSpellShortcut5", EShortcut::BATTLE_SPELL_SHORTCUT_5 }, + {"battleSpellShortcut6", EShortcut::BATTLE_SPELL_SHORTCUT_6 }, + {"battleSpellShortcut7", EShortcut::BATTLE_SPELL_SHORTCUT_7 }, + {"battleSpellShortcut8", EShortcut::BATTLE_SPELL_SHORTCUT_8 }, + {"battleSpellShortcut9", EShortcut::BATTLE_SPELL_SHORTCUT_9 }, {"spectateTrackHero", EShortcut::SPECTATE_TRACK_HERO }, {"spectateSkipBattle", EShortcut::SPECTATE_SKIP_BATTLE }, {"spectateSkipBattleResult", EShortcut::SPECTATE_SKIP_BATTLE_RESULT }, diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index 4359730be..3502b89d7 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -64,6 +64,16 @@ "battleOpenHoveredUnit": "V", "battleRetreat": "R", "battleSelectAction": "S", + "battleSpellShortcut0": "0", + "battleSpellShortcut1": "1", + "battleSpellShortcut2": "2", + "battleSpellShortcut3": "3", + "battleSpellShortcut4": "4", + "battleSpellShortcut5": "5", + "battleSpellShortcut6": "6", + "battleSpellShortcut7": "7", + "battleSpellShortcut8": "8", + "battleSpellShortcut9": "9", "battleSurrender": "S", "battleTacticsEnd": [ "Return", "Keypad Enter"], "battleTacticsNext": "Space", From fe408c203b58f2276c82d33ae946fed8a4057082 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 23:30:50 +0200 Subject: [PATCH 07/22] right click + tweak --- client/battle/BattleInterfaceClasses.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 2ea4015f0..1698e59e1 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -31,6 +31,7 @@ #include "../render/IFont.h" #include "../render/Graphics.h" #include "../widgets/Buttons.h" +#include "../widgets/CComponent.h" #include "../widgets/Images.h" #include "../widgets/Slider.h" #include "../widgets/TextControls.h" @@ -39,6 +40,7 @@ #include "../windows/CMessage.h" #include "../windows/CCreatureWindow.h" #include "../windows/CSpellWindow.h" +#include "../windows/InfoWindows.h" #include "../render/CAnimation.h" #include "../render/IRenderHandler.h" #include "../adventureMap/CInGameConsole.h" @@ -506,7 +508,7 @@ void QuickSpellPanel::mouseMoved(const Point & cursorPosition, const Point & las if( (cursorPosition.x <= initWidget->pos.x - 20 || cursorPosition.x >= initWidget->pos.x + initWidget->pos.w + 20 || cursorPosition.y <= initWidget->pos.y - pos.h - 20 || - (cursorPosition.y >= initWidget->pos.y && !initWidget->pos.isInside(cursorPosition))) && + (cursorPosition.y >= initWidget->pos.y + 5 && !initWidget->pos.isInside(cursorPosition))) && (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.resize(20).isInside(cursorPosition)) ) close(); @@ -552,6 +554,9 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) configID->String() = spell->identifier; parent->create(); }); + button->addPopupCallback([spell](){ + CRClickPopup::createAndPush(spell->getDescriptionTranslated(0), std::make_shared(ComponentType::SPELL, spell->id)); + }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), spellList[i]->getId().num + 1)); buttons.push_back(button); } From 13ebd026cc0827d382137565c74d605f2ea8a903 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sun, 19 May 2024 23:43:23 +0200 Subject: [PATCH 08/22] remove unnecassary conditions --- client/battle/BattleWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 76e3ed12f..235e98085 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -121,7 +121,7 @@ BattleWindow::BattleWindow(BattleInterface & Owner): if(w) { auto hero = owner.getBattle()->battleGetMyHero(); - if(GH.screenDimensions().x >= 1000 && hero && owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) != ESpellCastProblem::NO_SPELLBOOK && settings["general"]["enableUiEnhancements"].Bool()) + if(hero && settings["general"]["enableUiEnhancements"].Bool()) { auto createQuickSpellPanelWindow = [](std::shared_ptr widget, BattleInterface & owner){ std::shared_ptr window = std::make_shared(widget, owner); From 49cb9854521026b8d4f3a55b3c76dc631263792f Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 20 May 2024 00:28:08 +0200 Subject: [PATCH 09/22] try to fix ci --- client/battle/BattleInterfaceClasses.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 6033d983c..e65add84d 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -22,6 +22,7 @@ class CGHeroInstance; struct BattleResult; struct InfoAboutHero; class CStack; +class CPlayerBattleCallback; namespace battle { @@ -45,7 +46,6 @@ class CPlayerInterface; class BattleRenderer; class VideoWidget; class QuickSpellPanel; -class CPlayerBattleCallback; /// Class which shows the console at the bottom of the battle screen and manages the text of the console class BattleConsole : public CIntObject, public IStatusBar From 11664b27b804bb9b0312bc0c293685232546566b Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Fri, 21 Jun 2024 22:34:14 +0200 Subject: [PATCH 10/22] fix for develop --- client/battle/BattleInterfaceClasses.cpp | 15 ++++++++++++--- client/battle/BattleWindow.cpp | 10 +++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 1698e59e1..f71b9a377 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -449,7 +449,16 @@ void QuickSpellPanel::create() for(int i = 0; i < 10; i++) { std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); - SpellID id = SpellID::decode(spellIdentifier); + + SpellID id; + try + { + id = SpellID::decode(spellIdentifier); + } + catch(const IdentifierResolutionException& e) + { + id = SpellID::NONE; + } auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ if(id.hasValue() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) @@ -529,7 +538,7 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) setEnabled(false); - std::vector> spellList; + std::vector> spellList; for (auto const & s : VLC->spellh->objects) if (s->isCombat() && !s->isSpecial() && !s->isCreatureAbility()) spellList.push_back(s); @@ -545,7 +554,7 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) { int y = i % 10; int x = i / 10; - ConstTransitivePtr spell = spellList[i]; + std::shared_ptr spell = spellList[i]; auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, spell](){ setEnabled(false); GH.windows().totalRedraw(); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 235e98085..55472fe96 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -66,7 +66,15 @@ BattleWindow::BattleWindow(BattleInterface & Owner): auto useSpellIfPossible = [this](int slot){ std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(slot)].String(); - SpellID id = SpellID::decode(spellIdentifier); + SpellID id; + try + { + id = SpellID::decode(spellIdentifier); + } + catch(const IdentifierResolutionException& e) + { + return; + } if(id.hasValue() && owner.getBattle()->battleGetMyHero() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, owner.getBattle()->battleGetMyHero())) { owner.castThisSpell(id); From 37b5de689a56837962d9ae6b6f87cf1f73bf0acd Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Tue, 16 Jul 2024 22:47:40 +0200 Subject: [PATCH 11/22] move to left side --- client/battle/BattleInterfaceClasses.cpp | 89 ++++++++---------------- client/battle/BattleInterfaceClasses.h | 19 +++-- client/battle/BattleWindow.cpp | 44 +++++------- client/battle/BattleWindow.h | 3 + client/gui/Shortcut.h | 9 +++ client/gui/ShortcutHandler.cpp | 9 +++ config/shortcutsConfig.json | 9 +++ 7 files changed, 85 insertions(+), 97 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index f71b9a377..cf98b47e7 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -419,19 +419,17 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her addUsedEvents(TIME); } -QuickSpellPanel::QuickSpellPanel(std::shared_ptr initWidget, BattleInterface & owner) - : CWindowObject(NEEDS_ANIMATED_BACKGROUND), initWidget(initWidget), owner(owner) +QuickSpellPanel::QuickSpellPanel(BattleInterface & owner) + : CWindowObject(NEEDS_ANIMATED_BACKGROUND), owner(owner) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); addUsedEvents(LCLICK | SHOW_POPUP | MOVE); - pos = Rect(0, 0, 52, 372); + pos = Rect(0, 0, 52, 713); background = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); - panelSelect = std::make_shared(this); - create(); } @@ -447,7 +445,7 @@ void QuickSpellPanel::create() if(!hero) return; - for(int i = 0; i < 10; i++) { + for(int i = 0; i < 19; i++) { std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); SpellID id; @@ -460,24 +458,25 @@ void QuickSpellPanel::create() id = SpellID::NONE; } - auto button = std::make_shared(Point(2, 1 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ + auto button = std::make_shared(Point(2, 6 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ if(id.hasValue() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - close(); owner.castThisSpell(id); } }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), !spellIdentifier.empty() ? id.num + 1 : 0)); button->addPopupCallback([this, i](){ + auto panelSelect = std::make_shared(this); panelSelect->spellSlot = i; - panelSelect->setEnabled(true); + panelSelect->moveTo(Point(pos.x + 54, pos.y + 5)); + GH.windows().pushWindow(panelSelect); }); if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - buttonsDisabled.push_back(std::make_shared(Rect(2, 1 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); + buttonsDisabled.push_back(std::make_shared(Rect(2, 6 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); } - labels.push_back(std::make_shared(7, 4 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); + labels.push_back(std::make_shared(7, 9 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); buttons.push_back(button); } @@ -489,54 +488,12 @@ void QuickSpellPanel::show(Canvas & to) CIntObject::show(to); } -void QuickSpellPanel::clickReleased(const Point & cursorPosition) -{ - if(!pos.isInside(cursorPosition) && (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.isInside(cursorPosition))) - close(); - - if(initWidget->pos.isInside(cursorPosition)) - { - initWidget->clickPressed(cursorPosition); - initWidget->clickReleased(cursorPosition); - } -} - -void QuickSpellPanel::showPopupWindow(const Point & cursorPosition) -{ - if(!pos.isInside(cursorPosition) && (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.isInside(cursorPosition))) - close(); - - if(initWidget->pos.isInside(cursorPosition)) - { - initWidget->showPopupWindow(cursorPosition); - } -} - -void QuickSpellPanel::mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) -{ - if( (cursorPosition.x <= initWidget->pos.x - 20 || - cursorPosition.x >= initWidget->pos.x + initWidget->pos.w + 20 || - cursorPosition.y <= initWidget->pos.y - pos.h - 20 || - (cursorPosition.y >= initWidget->pos.y + 5 && !initWidget->pos.isInside(cursorPosition))) && - (!(panelSelect->isActive() || panelSelect->wasEnabled) || !panelSelect->pos.resize(20).isInside(cursorPosition)) - ) - close(); - - if(initWidget->pos.isInside(cursorPosition)) - panelSelect->wasEnabled = false; -} - -bool QuickSpellPanel::receiveEvent(const Point & position, int eventType) const -{ - return true; // capture click also outside of window -} - QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) - : parent(Parent), wasEnabled(false) + : parent(Parent) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - setEnabled(false); + addUsedEvents(LCLICK); std::vector> spellList; for (auto const & s : VLC->spellh->objects) @@ -544,21 +501,20 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) spellList.push_back(s); auto ceil = [](int x, int y){ return(x + y - 1) / y; }; - int columnsNeeded = ceil(spellList.size(), 10); + int columnsNeeded = ceil(spellList.size(), NUM_PER_COLUMN); - pos = Rect(-20 - columnsNeeded * 50, 0, columnsNeeded * 50 + 2, 372); + pos = Rect(pos.x, pos.y, columnsNeeded * 50 + 2, 2 + 37 * NUM_PER_COLUMN); background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); for(int i = 0; i < spellList.size(); i++) { - int y = i % 10; - int x = i / 10; + int y = i % NUM_PER_COLUMN; + int x = i / NUM_PER_COLUMN; std::shared_ptr spell = spellList[i]; auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, spell](){ - setEnabled(false); + close(); GH.windows().totalRedraw(); - wasEnabled = true; Settings configID = persistentStorage.write["quickSpell"][std::to_string(spellSlot)]; configID->String() = spell->identifier; parent->create(); @@ -571,6 +527,17 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) } } +void QuickSpellPanelSelect::clickReleased(const Point & cursorPosition) +{ + if(!pos.isInside(cursorPosition)) + close(); +} + +bool QuickSpellPanelSelect::receiveEvent(const Point & position, int eventType) const +{ + return true; // capture click also outside of window +} + HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground) : CIntObject(0) { diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index e65add84d..9560079ef 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -149,16 +149,21 @@ public: BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender); }; -class QuickSpellPanelSelect : public CIntObject +class QuickSpellPanelSelect : public CWindowObject { private: + const int NUM_PER_COLUMN = 19; + std::shared_ptr background; std::shared_ptr rect; std::vector> buttons; QuickSpellPanel * parent; public: QuickSpellPanelSelect(QuickSpellPanel * Parent); - bool wasEnabled; // was the panel opened? -> don't close window because mouse is not in area + + bool receiveEvent(const Point & position, int eventType) const override; + void clickReleased(const Point & cursorPosition) override; + int spellSlot; }; @@ -171,17 +176,9 @@ private: std::vector> buttonsDisabled; std::vector> labels; - std::shared_ptr panelSelect; - - bool receiveEvent(const Point & position, int eventType) const override; - void clickReleased(const Point & cursorPosition) override; - void showPopupWindow(const Point & cursorPosition) override; - void mouseMoved(const Point & cursorPosition, const Point & lastUpdateDistance) override; - - std::shared_ptr initWidget; BattleInterface & owner; public: - QuickSpellPanel(std::shared_ptr initWidget, BattleInterface & owner); + QuickSpellPanel(BattleInterface & owner); void create(); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 55472fe96..0046b51b6 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -90,6 +90,15 @@ BattleWindow::BattleWindow(BattleInterface & Owner): addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [useSpellIfPossible](){ useSpellIfPossible(7); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [useSpellIfPossible](){ useSpellIfPossible(8); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [useSpellIfPossible](){ useSpellIfPossible(9); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_10, [useSpellIfPossible](){ useSpellIfPossible(10); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_11, [useSpellIfPossible](){ useSpellIfPossible(11); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_12, [useSpellIfPossible](){ useSpellIfPossible(12); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_13, [useSpellIfPossible](){ useSpellIfPossible(13); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_14, [useSpellIfPossible](){ useSpellIfPossible(14); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_15, [useSpellIfPossible](){ useSpellIfPossible(15); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_16, [useSpellIfPossible](){ useSpellIfPossible(16); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_17, [useSpellIfPossible](){ useSpellIfPossible(17); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_18, [useSpellIfPossible](){ useSpellIfPossible(18); }); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); @@ -123,33 +132,9 @@ BattleWindow::BattleWindow(BattleInterface & Owner): createQueue(); createStickyHeroInfoWindows(); + createQuickSpellWindow(); createTimerInfoWindows(); - auto w = widget("cast"); - if(w) - { - auto hero = owner.getBattle()->battleGetMyHero(); - if(hero && settings["general"]["enableUiEnhancements"].Bool()) - { - auto createQuickSpellPanelWindow = [](std::shared_ptr widget, BattleInterface & owner){ - std::shared_ptr window = std::make_shared(widget, owner); - window->moveTo(Point(widget->pos.x - 2, widget->pos.y - 378)); - GH.windows().pushWindow(window); - }; - - w->addHoverCallback([this, createQuickSpellPanelWindow, w](bool on) - { - if(on) - createQuickSpellPanelWindow(w, owner); - }); - w->addPanningCallback([this, createQuickSpellPanelWindow, w](const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) - { - if((currentPosition - initialPosition).y < -20) - createQuickSpellPanelWindow(w, owner); - }); - } - } - if ( owner.tacticsMode ) tacticPhaseStarted(); else @@ -216,6 +201,15 @@ void BattleWindow::createStickyHeroInfoWindows() setPositionInfoWindow(); } +void BattleWindow::createQuickSpellWindow() +{ + OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + + std::shared_ptr window = std::make_shared(owner); + window->moveTo(Point(pos.x - 68, pos.y - 14)); + GH.windows().pushWindow(window); +} + void BattleWindow::createTimerInfoWindows() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; diff --git a/client/battle/BattleWindow.h b/client/battle/BattleWindow.h index 27897df45..15dfaf235 100644 --- a/client/battle/BattleWindow.h +++ b/client/battle/BattleWindow.h @@ -41,6 +41,8 @@ class BattleWindow : public InterfaceObjectConfigurable std::shared_ptr attackerStackWindow; std::shared_ptr defenderStackWindow; + std::shared_ptr quickSpellWindow; + std::shared_ptr attackerTimerWidget; std::shared_ptr defenderTimerWidget; @@ -75,6 +77,7 @@ class BattleWindow : public InterfaceObjectConfigurable void toggleStickyHeroWindowsVisibility(); void createStickyHeroInfoWindows(); + void createQuickSpellWindow(); void createTimerInfoWindows(); std::shared_ptr buildBattleConsole(const JsonNode &) const; diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index 42b96ac1c..1fb40020f 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -196,6 +196,15 @@ enum class EShortcut BATTLE_SPELL_SHORTCUT_7, BATTLE_SPELL_SHORTCUT_8, BATTLE_SPELL_SHORTCUT_9, + BATTLE_SPELL_SHORTCUT_10, + BATTLE_SPELL_SHORTCUT_11, + BATTLE_SPELL_SHORTCUT_12, + BATTLE_SPELL_SHORTCUT_13, + BATTLE_SPELL_SHORTCUT_14, + BATTLE_SPELL_SHORTCUT_15, + BATTLE_SPELL_SHORTCUT_16, + BATTLE_SPELL_SHORTCUT_17, + BATTLE_SPELL_SHORTCUT_18, MARKET_DEAL, MARKET_MAX_AMOUNT, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index 11bafc8ae..18b4065b8 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -232,6 +232,15 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"battleSpellShortcut7", EShortcut::BATTLE_SPELL_SHORTCUT_7 }, {"battleSpellShortcut8", EShortcut::BATTLE_SPELL_SHORTCUT_8 }, {"battleSpellShortcut9", EShortcut::BATTLE_SPELL_SHORTCUT_9 }, + {"battleSpellShortcut10", EShortcut::BATTLE_SPELL_SHORTCUT_10 }, + {"battleSpellShortcut11", EShortcut::BATTLE_SPELL_SHORTCUT_11 }, + {"battleSpellShortcut12", EShortcut::BATTLE_SPELL_SHORTCUT_12 }, + {"battleSpellShortcut13", EShortcut::BATTLE_SPELL_SHORTCUT_13 }, + {"battleSpellShortcut14", EShortcut::BATTLE_SPELL_SHORTCUT_14 }, + {"battleSpellShortcut15", EShortcut::BATTLE_SPELL_SHORTCUT_15 }, + {"battleSpellShortcut16", EShortcut::BATTLE_SPELL_SHORTCUT_16 }, + {"battleSpellShortcut17", EShortcut::BATTLE_SPELL_SHORTCUT_17 }, + {"battleSpellShortcut18", EShortcut::BATTLE_SPELL_SHORTCUT_18 }, {"spectateTrackHero", EShortcut::SPECTATE_TRACK_HERO }, {"spectateSkipBattle", EShortcut::SPECTATE_SKIP_BATTLE }, {"spectateSkipBattleResult", EShortcut::SPECTATE_SKIP_BATTLE_RESULT }, diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index 3502b89d7..d6ba7bf7d 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -74,6 +74,15 @@ "battleSpellShortcut7": "7", "battleSpellShortcut8": "8", "battleSpellShortcut9": "9", + "battleSpellShortcut10": "Shift+0", + "battleSpellShortcut11": "Shift+1", + "battleSpellShortcut12": "Shift+2", + "battleSpellShortcut13": "Shift+3", + "battleSpellShortcut14": "Shift+4", + "battleSpellShortcut15": "Shift+5", + "battleSpellShortcut16": "Shift+6", + "battleSpellShortcut17": "Shift+7", + "battleSpellShortcut18": "Shift+8", "battleSurrender": "S", "battleTacticsEnd": [ "Return", "Keypad Enter"], "battleTacticsNext": "Space", From 1daf6dfad1ecdfda2497999cea561fe9783e51ac Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Tue, 16 Jul 2024 23:36:23 +0200 Subject: [PATCH 12/22] make hideable --- client/battle/BattleInterfaceClasses.cpp | 2 +- client/battle/BattleInterfaceClasses.h | 2 +- client/battle/BattleWindow.cpp | 45 ++++++++++++++++++++++-- client/battle/BattleWindow.h | 5 +++ client/gui/Shortcut.h | 1 + client/gui/ShortcutHandler.cpp | 1 + config/schemas/settings.json | 6 +++- config/shortcutsConfig.json | 1 + 8 files changed, 57 insertions(+), 6 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index cf98b47e7..0bde51b3d 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -420,7 +420,7 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her } QuickSpellPanel::QuickSpellPanel(BattleInterface & owner) - : CWindowObject(NEEDS_ANIMATED_BACKGROUND), owner(owner) + : CIntObject(0), owner(owner) { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 9560079ef..149b24390 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -167,7 +167,7 @@ public: int spellSlot; }; -class QuickSpellPanel : public CWindowObject +class QuickSpellPanel : public CIntObject { private: std::shared_ptr background; diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 0046b51b6..28b30af42 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -80,6 +80,7 @@ BattleWindow::BattleWindow(BattleInterface & Owner): owner.castThisSpell(id); } }; + addShortcut(EShortcut::BATTLE_TOGGLE_QUICKSPELL, [this](){ this->toggleStickyQuickSpellVisibility();}); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [useSpellIfPossible](){ useSpellIfPossible(0); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [useSpellIfPossible](){ useSpellIfPossible(1); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [useSpellIfPossible](){ useSpellIfPossible(2); }); @@ -205,9 +206,47 @@ void BattleWindow::createQuickSpellWindow() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - std::shared_ptr window = std::make_shared(owner); - window->moveTo(Point(pos.x - 68, pos.y - 14)); - GH.windows().pushWindow(window); + quickSpellWindow = std::make_shared(owner); + quickSpellWindow->moveTo(Point(pos.x - 68, pos.y - 14)); + + if(settings["battle"]["enableQuickSpellPanel"].Bool()) + showStickyQuickSpellWindow(); + else + hideStickyQuickSpellWindow(); +} + +void BattleWindow::toggleStickyQuickSpellVisibility() +{ + if(settings["battle"]["enableQuickSpellPanel"].Bool()) + hideStickyQuickSpellWindow(); + else + showStickyQuickSpellWindow(); +} + +void BattleWindow::hideStickyQuickSpellWindow() +{ + if(settings["battle"]["enableQuickSpellPanel"].Bool() == false) + return; + + Settings showStickyQuickSpellWindow = settings.write["battle"]["enableQuickSpellPanel"]; + showStickyQuickSpellWindow->Bool() = false; + + quickSpellWindow->disable(); + + GH.windows().totalRedraw(); +} + +void BattleWindow::showStickyQuickSpellWindow() +{ + if(settings["battle"]["enableQuickSpellPanel"].Bool() == true) + return; + + Settings showStickyQuickSpellWindow = settings.write["battle"]["enableQuickSpellPanel"]; + showStickyQuickSpellWindow->Bool() = true; + + quickSpellWindow->enable(); + + GH.windows().totalRedraw(); } void BattleWindow::createTimerInfoWindows() diff --git a/client/battle/BattleWindow.h b/client/battle/BattleWindow.h index 15dfaf235..d5b21657a 100644 --- a/client/battle/BattleWindow.h +++ b/client/battle/BattleWindow.h @@ -76,6 +76,7 @@ class BattleWindow : public InterfaceObjectConfigurable void createQueue(); void toggleStickyHeroWindowsVisibility(); + void toggleStickyQuickSpellVisibility(); void createStickyHeroInfoWindows(); void createQuickSpellWindow(); void createTimerInfoWindows(); @@ -98,6 +99,10 @@ public: void hideStickyHeroWindows(); void showStickyHeroWindows(); + /// Toggle permanent quickspell windows visibility + void hideStickyQuickSpellWindow(); + void showStickyQuickSpellWindow(); + /// Event handler for netpack changing hero mana points void heroManaPointsChanged(const CGHeroInstance * hero); diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index 1fb40020f..5193cd91e 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -186,6 +186,7 @@ enum class EShortcut BATTLE_TOGGLE_HEROES_STATS, BATTLE_OPEN_ACTIVE_UNIT, BATTLE_OPEN_HOVERED_UNIT, + BATTLE_TOGGLE_QUICKSPELL, BATTLE_SPELL_SHORTCUT_0, BATTLE_SPELL_SHORTCUT_1, BATTLE_SPELL_SHORTCUT_2, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index 18b4065b8..aaf480a6a 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -222,6 +222,7 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"battleTacticsNext", EShortcut::BATTLE_TACTICS_NEXT }, {"battleTacticsEnd", EShortcut::BATTLE_TACTICS_END }, {"battleSelectAction", EShortcut::BATTLE_SELECT_ACTION }, + {"battleToggleQuickSpell", EShortcut::BATTLE_TOGGLE_QUICKSPELL }, {"battleSpellShortcut0", EShortcut::BATTLE_SPELL_SHORTCUT_0 }, {"battleSpellShortcut1", EShortcut::BATTLE_SPELL_SHORTCUT_1 }, {"battleSpellShortcut2", EShortcut::BATTLE_SPELL_SHORTCUT_2 }, diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 002500054..56c97240b 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -372,7 +372,7 @@ "type" : "object", "additionalProperties" : false, "default" : {}, - "required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "movementHighlightOnHover", "rangeLimitHighlightOnHover", "showQueue", "swipeAttackDistance", "queueSize", "stickyHeroInfoWindows", "enableAutocombatSpells", "endWithAutocombat", "queueSmallSlots", "queueSmallOutside" ], + "required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "movementHighlightOnHover", "rangeLimitHighlightOnHover", "showQueue", "swipeAttackDistance", "queueSize", "stickyHeroInfoWindows", "enableAutocombatSpells", "endWithAutocombat", "queueSmallSlots", "queueSmallOutside", "enableQuickSpellPanel" ], "properties" : { "speedFactor" : { "type" : "number", @@ -430,6 +430,10 @@ "queueSmallOutside" : { "type": "boolean", "default": false + }, + "enableQuickSpellPanel" : { + "type": "boolean", + "default": true } } }, diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index d6ba7bf7d..744b110ac 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -64,6 +64,7 @@ "battleOpenHoveredUnit": "V", "battleRetreat": "R", "battleSelectAction": "S", + "battleToggleQuickSpell": "T", "battleSpellShortcut0": "0", "battleSpellShortcut1": "1", "battleSpellShortcut2": "2", From a3874297f5efaa1ed0ce841b9ddd5f18e2504a90 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 00:48:22 +0200 Subject: [PATCH 13/22] toggle window --- client/battle/BattleWindow.cpp | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 28b30af42..24e596402 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -132,8 +132,8 @@ BattleWindow::BattleWindow(BattleInterface & Owner): owner.fieldController->createHeroes(); createQueue(); - createStickyHeroInfoWindows(); createQuickSpellWindow(); + createStickyHeroInfoWindows(); createTimerInfoWindows(); if ( owner.tacticsMode ) @@ -225,27 +225,28 @@ void BattleWindow::toggleStickyQuickSpellVisibility() void BattleWindow::hideStickyQuickSpellWindow() { - if(settings["battle"]["enableQuickSpellPanel"].Bool() == false) - return; - Settings showStickyQuickSpellWindow = settings.write["battle"]["enableQuickSpellPanel"]; showStickyQuickSpellWindow->Bool() = false; quickSpellWindow->disable(); + setPositionInfoWindow(); + createTimerInfoWindows(); GH.windows().totalRedraw(); } void BattleWindow::showStickyQuickSpellWindow() { - if(settings["battle"]["enableQuickSpellPanel"].Bool() == true) - return; - Settings showStickyQuickSpellWindow = settings.write["battle"]["enableQuickSpellPanel"]; showStickyQuickSpellWindow->Bool() = true; - quickSpellWindow->enable(); + if(GH.screenDimensions().x >= 1050) + quickSpellWindow->enable(); + else + quickSpellWindow->disable(); + setPositionInfoWindow(); + createTimerInfoWindows(); GH.windows().totalRedraw(); } @@ -253,6 +254,8 @@ void BattleWindow::createTimerInfoWindows() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; + int xOffsetAttacker = quickSpellWindow->isActive() ? -53 : 0; + if(LOCPLINT->cb->getStartInfo()->turnTimerInfo.battleTimer != 0 || LOCPLINT->cb->getStartInfo()->turnTimerInfo.unitTimer != 0) { PlayerColor attacker = owner.getBattle()->sideToPlayer(BattleSide::ATTACKER); @@ -261,7 +264,7 @@ void BattleWindow::createTimerInfoWindows() if (attacker.isValidPlayer()) { if (GH.screenDimensions().x >= 1000) - attackerTimerWidget = std::make_shared(Point(-92, 1), attacker); + attackerTimerWidget = std::make_shared(Point(-92 + xOffsetAttacker, 1), attacker); else attackerTimerWidget = std::make_shared(Point(1, 135), attacker); } @@ -372,6 +375,7 @@ void BattleWindow::updateQueue() void BattleWindow::setPositionInfoWindow() { + int xOffsetAttacker = quickSpellWindow->isActive() ? -53 : 0; if(defenderHeroWindow) { Point position = (GH.screenDimensions().x >= 1000) @@ -382,7 +386,7 @@ void BattleWindow::setPositionInfoWindow() if(attackerHeroWindow) { Point position = (GH.screenDimensions().x >= 1000) - ? Point(pos.x - 93, pos.y + 60) + ? Point(pos.x - 93 + xOffsetAttacker, pos.y + 60) : Point(pos.x + 1, pos.y + 195); attackerHeroWindow->moveTo(position); } @@ -396,7 +400,7 @@ void BattleWindow::setPositionInfoWindow() if(attackerStackWindow) { Point position = (GH.screenDimensions().x >= 1000) - ? Point(pos.x - 93, attackerHeroWindow ? attackerHeroWindow->pos.y + 210 : pos.y + 60) + ? Point(pos.x - 93 + xOffsetAttacker, attackerHeroWindow ? attackerHeroWindow->pos.y + 210 : pos.y + 60) : Point(pos.x + 1, attackerHeroWindow ? attackerHeroWindow->pos.y : pos.y + 195); attackerStackWindow->moveTo(position); } @@ -431,6 +435,7 @@ void BattleWindow::updateStackInfoWindow(const CStack * stack) attackerStackWindow = nullptr; setPositionInfoWindow(); + createTimerInfoWindows(); } void BattleWindow::heroManaPointsChanged(const CGHeroInstance * hero) @@ -851,6 +856,8 @@ void BattleWindow::blockUI(bool on) setShortcutBlocked(EShortcut::BATTLE_TACTICS_NEXT, on || !owner.tacticsMode); setShortcutBlocked(EShortcut::BATTLE_CONSOLE_DOWN, on && !owner.tacticsMode); setShortcutBlocked(EShortcut::BATTLE_CONSOLE_UP, on && !owner.tacticsMode); + + quickSpellWindow->setInputEnabled(!on); } void BattleWindow::bOpenActiveUnit() From 0a98169bcfe86e083d427237b8e04057a8208c45 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 00:55:01 +0200 Subject: [PATCH 14/22] update quick spell panel --- client/battle/BattleWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 24e596402..e9fe93486 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -371,6 +371,7 @@ void BattleWindow::showStickyHeroWindows() void BattleWindow::updateQueue() { queue->update(); + createQuickSpellWindow(); } void BattleWindow::setPositionInfoWindow() From d23d4b32c7537276858ba0c438d2ddb66b2b5872 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 01:02:11 +0200 Subject: [PATCH 15/22] cleanup --- client/widgets/Buttons.cpp | 19 +------------------ client/widgets/Buttons.h | 5 ----- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/client/widgets/Buttons.cpp b/client/widgets/Buttons.cpp index 8491afe3e..4ab499cd7 100644 --- a/client/widgets/Buttons.cpp +++ b/client/widgets/Buttons.cpp @@ -72,16 +72,6 @@ void CButton::addPopupCallback(const std::function & callback) this->callbackPopup += callback; } -void CButton::addHoverCallback(const std::function & callback) -{ - this->hoverCallback += callback; -} - -void CButton::addPanningCallback(const std::function & callback) -{ - this->panningCallback += callback; -} - void ButtonBase::setTextOverlay(const std::string & Text, EFonts font, ColorRGBA color) { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); @@ -312,8 +302,6 @@ void CButton::showPopupWindow(const Point & cursorPosition) void CButton::hover (bool on) { - hoverCallback(on); - if(hoverable && !isBlocked()) { if(on) @@ -338,11 +326,6 @@ void CButton::hover (bool on) } } -void CButton::gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) -{ - panningCallback(initialPosition, currentPosition, lastUpdateDistance); -} - ButtonBase::ButtonBase(Point position, const AnimationPath & defName, EShortcut key, bool playerColoredButton) : CKeyShortcut(key) , stateToIndex({0, 1, 2, 3}) @@ -375,7 +358,7 @@ CButton::CButton(Point position, const AnimationPath &defName, const std::pair callback; CFunctionList callbackPopup; - CFunctionList hoverCallback; - CFunctionList panningCallback; std::array hoverTexts; //texts for statusbar, if empty - first entry will be used std::optional borderColor; // mapping of button state to border color @@ -94,8 +92,6 @@ public: /// adds one more callback to on-click actions void addCallback(const std::function & callback); void addPopupCallback(const std::function & callback); - void addHoverCallback(const std::function & callback); - void addPanningCallback(const std::function & callback); void addHoverText(EButtonState state, const std::string & text); @@ -120,7 +116,6 @@ public: void clickReleased(const Point & cursorPosition) override; void clickCancel(const Point & cursorPosition) override; void hover (bool on) override; - void gesturePanning(const Point & initialPosition, const Point & currentPosition, const Point & lastUpdateDistance) override; void showAll(Canvas & to) override; /// generates tooltip that can be passed into constructor From b8d872aa6049d3e887bd7251b6de43b9d13059c9 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 04:24:27 +0200 Subject: [PATCH 16/22] mobile adjustments --- client/battle/BattleInterfaceClasses.cpp | 14 ++++++------- client/battle/BattleInterfaceClasses.h | 2 +- client/battle/BattleWindow.cpp | 25 +++++++++++------------- client/gui/Shortcut.h | 3 --- client/gui/ShortcutHandler.cpp | 3 --- config/shortcutsConfig.json | 3 --- 6 files changed, 19 insertions(+), 31 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 0bde51b3d..1ae1acd44 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -426,7 +426,7 @@ QuickSpellPanel::QuickSpellPanel(BattleInterface & owner) addUsedEvents(LCLICK | SHOW_POPUP | MOVE); - pos = Rect(0, 0, 52, 713); + pos = Rect(0, 0, 52, 600); background = std::make_shared(ImagePath::builtin("DIBOXBCK"), pos); rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); @@ -445,7 +445,7 @@ void QuickSpellPanel::create() if(!hero) return; - for(int i = 0; i < 19; i++) { + for(int i = 0; i < 16; i++) { std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); SpellID id; @@ -458,7 +458,7 @@ void QuickSpellPanel::create() id = SpellID::NONE; } - auto button = std::make_shared(Point(2, 6 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ + auto button = std::make_shared(Point(2, 5 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ if(id.hasValue() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { owner.castThisSpell(id); @@ -468,15 +468,15 @@ void QuickSpellPanel::create() button->addPopupCallback([this, i](){ auto panelSelect = std::make_shared(this); panelSelect->spellSlot = i; - panelSelect->moveTo(Point(pos.x + 54, pos.y + 5)); + panelSelect->moveTo(Point(pos.x + 54, pos.y + 4)); GH.windows().pushWindow(panelSelect); }); if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - buttonsDisabled.push_back(std::make_shared(Rect(2, 6 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); + buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); } - labels.push_back(std::make_shared(7, 9 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); + labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); buttons.push_back(button); } @@ -529,7 +529,7 @@ QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) void QuickSpellPanelSelect::clickReleased(const Point & cursorPosition) { - if(!pos.isInside(cursorPosition)) + if(!pos.isInside(cursorPosition) && !parent->pos.isInside(cursorPosition)) close(); } diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 149b24390..5fe9049eb 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -152,7 +152,7 @@ public: class QuickSpellPanelSelect : public CWindowObject { private: - const int NUM_PER_COLUMN = 19; + const int NUM_PER_COLUMN = 16; std::shared_ptr background; std::shared_ptr rect; diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index e9fe93486..f641a516a 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -81,25 +81,22 @@ BattleWindow::BattleWindow(BattleInterface & Owner): } }; addShortcut(EShortcut::BATTLE_TOGGLE_QUICKSPELL, [this](){ this->toggleStickyQuickSpellVisibility();}); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [useSpellIfPossible](){ useSpellIfPossible(0); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [useSpellIfPossible](){ useSpellIfPossible(1); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [useSpellIfPossible](){ useSpellIfPossible(2); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_3, [useSpellIfPossible](){ useSpellIfPossible(3); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_4, [useSpellIfPossible](){ useSpellIfPossible(4); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_5, [useSpellIfPossible](){ useSpellIfPossible(5); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_6, [useSpellIfPossible](){ useSpellIfPossible(6); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [useSpellIfPossible](){ useSpellIfPossible(7); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [useSpellIfPossible](){ useSpellIfPossible(8); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [useSpellIfPossible](){ useSpellIfPossible(9); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [useSpellIfPossible](){ useSpellIfPossible(0); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [useSpellIfPossible](){ useSpellIfPossible(1); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [useSpellIfPossible](){ useSpellIfPossible(2); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_3, [useSpellIfPossible](){ useSpellIfPossible(3); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_4, [useSpellIfPossible](){ useSpellIfPossible(4); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_5, [useSpellIfPossible](){ useSpellIfPossible(5); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_6, [useSpellIfPossible](){ useSpellIfPossible(6); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [useSpellIfPossible](){ useSpellIfPossible(7); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [useSpellIfPossible](){ useSpellIfPossible(8); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [useSpellIfPossible](){ useSpellIfPossible(9); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_10, [useSpellIfPossible](){ useSpellIfPossible(10); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_11, [useSpellIfPossible](){ useSpellIfPossible(11); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_12, [useSpellIfPossible](){ useSpellIfPossible(12); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_13, [useSpellIfPossible](){ useSpellIfPossible(13); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_14, [useSpellIfPossible](){ useSpellIfPossible(14); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_15, [useSpellIfPossible](){ useSpellIfPossible(15); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_16, [useSpellIfPossible](){ useSpellIfPossible(16); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_17, [useSpellIfPossible](){ useSpellIfPossible(17); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_18, [useSpellIfPossible](){ useSpellIfPossible(18); }); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); @@ -207,7 +204,7 @@ void BattleWindow::createQuickSpellWindow() OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; quickSpellWindow = std::make_shared(owner); - quickSpellWindow->moveTo(Point(pos.x - 68, pos.y - 14)); + quickSpellWindow->moveTo(Point(pos.x - 67, pos.y - 1)); if(settings["battle"]["enableQuickSpellPanel"].Bool()) showStickyQuickSpellWindow(); diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index 5193cd91e..57027fa44 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -203,9 +203,6 @@ enum class EShortcut BATTLE_SPELL_SHORTCUT_13, BATTLE_SPELL_SHORTCUT_14, BATTLE_SPELL_SHORTCUT_15, - BATTLE_SPELL_SHORTCUT_16, - BATTLE_SPELL_SHORTCUT_17, - BATTLE_SPELL_SHORTCUT_18, MARKET_DEAL, MARKET_MAX_AMOUNT, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index aaf480a6a..9e6ce0e96 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -239,9 +239,6 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"battleSpellShortcut13", EShortcut::BATTLE_SPELL_SHORTCUT_13 }, {"battleSpellShortcut14", EShortcut::BATTLE_SPELL_SHORTCUT_14 }, {"battleSpellShortcut15", EShortcut::BATTLE_SPELL_SHORTCUT_15 }, - {"battleSpellShortcut16", EShortcut::BATTLE_SPELL_SHORTCUT_16 }, - {"battleSpellShortcut17", EShortcut::BATTLE_SPELL_SHORTCUT_17 }, - {"battleSpellShortcut18", EShortcut::BATTLE_SPELL_SHORTCUT_18 }, {"spectateTrackHero", EShortcut::SPECTATE_TRACK_HERO }, {"spectateSkipBattle", EShortcut::SPECTATE_SKIP_BATTLE }, {"spectateSkipBattleResult", EShortcut::SPECTATE_SKIP_BATTLE_RESULT }, diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index 744b110ac..f637e6b52 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -81,9 +81,6 @@ "battleSpellShortcut13": "Shift+3", "battleSpellShortcut14": "Shift+4", "battleSpellShortcut15": "Shift+5", - "battleSpellShortcut16": "Shift+6", - "battleSpellShortcut17": "Shift+7", - "battleSpellShortcut18": "Shift+8", "battleSurrender": "S", "battleTacticsEnd": [ "Return", "Keypad Enter"], "battleTacticsNext": "Space", From 55624026468f2ad7132ebe28e9a47a0953230128 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 12:37:23 +0200 Subject: [PATCH 17/22] hotkey number from config --- client/battle/BattleInterfaceClasses.cpp | 6 ++++- client/battle/BattleWindow.cpp | 2 +- config/shortcutsConfig.json | 32 ++++++++++++------------ 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 1ae1acd44..62d37c989 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -57,6 +57,8 @@ #include "../../lib/mapObjects/CGTownInstance.h" #include "../../lib/networkPacks/PacksForClientBattle.h" #include "../../lib/TextOperations.h" +#include "../../lib/json/JsonUtils.h" + void BattleConsole::showAll(Canvas & to) { @@ -437,6 +439,8 @@ void QuickSpellPanel::create() { OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); + const JsonNode config = JsonUtils::assembleFromFiles("config/shortcutsConfig"); + labels.clear(); buttons.clear(); buttonsDisabled.clear(); @@ -476,7 +480,7 @@ void QuickSpellPanel::create() { buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); } - labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, std::to_string(i))); + labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String())); buttons.push_back(button); } diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index f641a516a..67e416502 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -204,7 +204,7 @@ void BattleWindow::createQuickSpellWindow() OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; quickSpellWindow = std::make_shared(owner); - quickSpellWindow->moveTo(Point(pos.x - 67, pos.y - 1)); + quickSpellWindow->moveTo(Point(pos.x - 67, pos.y)); if(settings["battle"]["enableQuickSpellPanel"].Bool()) showStickyQuickSpellWindow(); diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index f637e6b52..caf62161d 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -65,22 +65,22 @@ "battleRetreat": "R", "battleSelectAction": "S", "battleToggleQuickSpell": "T", - "battleSpellShortcut0": "0", - "battleSpellShortcut1": "1", - "battleSpellShortcut2": "2", - "battleSpellShortcut3": "3", - "battleSpellShortcut4": "4", - "battleSpellShortcut5": "5", - "battleSpellShortcut6": "6", - "battleSpellShortcut7": "7", - "battleSpellShortcut8": "8", - "battleSpellShortcut9": "9", - "battleSpellShortcut10": "Shift+0", - "battleSpellShortcut11": "Shift+1", - "battleSpellShortcut12": "Shift+2", - "battleSpellShortcut13": "Shift+3", - "battleSpellShortcut14": "Shift+4", - "battleSpellShortcut15": "Shift+5", + "battleSpellShortcut0": "1", + "battleSpellShortcut1": "2", + "battleSpellShortcut2": "3", + "battleSpellShortcut3": "4", + "battleSpellShortcut4": "5", + "battleSpellShortcut5": "6", + "battleSpellShortcut6": "7", + "battleSpellShortcut7": "8", + "battleSpellShortcut8": "Shift+1", + "battleSpellShortcut9": "Shift+2", + "battleSpellShortcut10": "Shift+3", + "battleSpellShortcut11": "Shift+4", + "battleSpellShortcut12": "Shift+5", + "battleSpellShortcut13": "Shift+6", + "battleSpellShortcut14": "Shift+7", + "battleSpellShortcut15": "Shift+8", "battleSurrender": "S", "battleTacticsEnd": [ "Return", "Keypad Enter"], "battleTacticsNext": "Space", From f54b84ead94a286a3dca9949ed66407a1f9871a4 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:20:17 +0200 Subject: [PATCH 18/22] use spellbook to select --- client/battle/BattleInterfaceClasses.cpp | 61 +++--------------------- client/battle/BattleInterfaceClasses.h | 18 ------- client/windows/CSpellWindow.cpp | 21 +++++++- client/windows/CSpellWindow.h | 5 +- 4 files changed, 29 insertions(+), 76 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 62d37c989..516ddceed 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -469,11 +469,12 @@ void QuickSpellPanel::create() } }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), !spellIdentifier.empty() ? id.num + 1 : 0)); - button->addPopupCallback([this, i](){ - auto panelSelect = std::make_shared(this); - panelSelect->spellSlot = i; - panelSelect->moveTo(Point(pos.x + 54, pos.y + 4)); - GH.windows().pushWindow(panelSelect); + button->addPopupCallback([this, i, hero](){ + GH.windows().createAndPushWindow(hero, owner.curInt.get(), true, [this, i](SpellID spell){ + Settings configID = persistentStorage.write["quickSpell"][std::to_string(i)]; + configID->String() = spell.toSpell()->identifier; + create(); + }); }); if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) @@ -492,56 +493,6 @@ void QuickSpellPanel::show(Canvas & to) CIntObject::show(to); } -QuickSpellPanelSelect::QuickSpellPanelSelect(QuickSpellPanel * Parent) - : parent(Parent) -{ - OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); - - addUsedEvents(LCLICK); - - std::vector> spellList; - for (auto const & s : VLC->spellh->objects) - if (s->isCombat() && !s->isSpecial() && !s->isCreatureAbility()) - spellList.push_back(s); - - auto ceil = [](int x, int y){ return(x + y - 1) / y; }; - int columnsNeeded = ceil(spellList.size(), NUM_PER_COLUMN); - - pos = Rect(pos.x, pos.y, columnsNeeded * 50 + 2, 2 + 37 * NUM_PER_COLUMN); - background = std::make_shared(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h)); - rect = std::make_shared(Rect(0, 0, pos.w + 1, pos.h + 1), ColorRGBA(0, 0, 0, 0), ColorRGBA(241, 216, 120, 255)); - - for(int i = 0; i < spellList.size(); i++) - { - int y = i % NUM_PER_COLUMN; - int x = i / NUM_PER_COLUMN; - std::shared_ptr spell = spellList[i]; - auto button = std::make_shared(Point(2 + 50 * x, 1 + 37 * y), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, spell](){ - close(); - GH.windows().totalRedraw(); - Settings configID = persistentStorage.write["quickSpell"][std::to_string(spellSlot)]; - configID->String() = spell->identifier; - parent->create(); - }); - button->addPopupCallback([spell](){ - CRClickPopup::createAndPush(spell->getDescriptionTranslated(0), std::make_shared(ComponentType::SPELL, spell->id)); - }); - button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), spellList[i]->getId().num + 1)); - buttons.push_back(button); - } -} - -void QuickSpellPanelSelect::clickReleased(const Point & cursorPosition) -{ - if(!pos.isInside(cursorPosition) && !parent->pos.isInside(cursorPosition)) - close(); -} - -bool QuickSpellPanelSelect::receiveEvent(const Point & position, int eventType) const -{ - return true; // capture click also outside of window -} - HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground) : CIntObject(0) { diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 5fe9049eb..9cce7143e 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -149,24 +149,6 @@ public: BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender); }; -class QuickSpellPanelSelect : public CWindowObject -{ -private: - const int NUM_PER_COLUMN = 16; - - std::shared_ptr background; - std::shared_ptr rect; - std::vector> buttons; - QuickSpellPanel * parent; -public: - QuickSpellPanelSelect(QuickSpellPanel * Parent); - - bool receiveEvent(const Point & position, int eventType) const override; - void clickReleased(const Point & cursorPosition) override; - - int spellSlot; -}; - class QuickSpellPanel : public CIntObject { private: diff --git a/client/windows/CSpellWindow.cpp b/client/windows/CSpellWindow.cpp index 5c89602c3..e91cbbada 100644 --- a/client/windows/CSpellWindow.cpp +++ b/client/windows/CSpellWindow.cpp @@ -98,13 +98,15 @@ public: } }; -CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells): +CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells, std::function onSpellSelect): CWindowObject(PLAYER_COLORED | (settings["gameTweaks"]["enableLargeSpellbook"].Bool() ? BORDERED : 0)), battleSpellsOnly(openOnBattleSpells), selectedTab(4), currentPage(0), myHero(_myHero), myInt(_myInt), + openOnBattleSpells(openOnBattleSpells), + onSpellSelect(onSpellSelect), isBigSpellbook(settings["gameTweaks"]["enableLargeSpellbook"].Bool()), spellsPerPage(24), offL(-11), @@ -293,6 +295,14 @@ void CSpellWindow::processSpells() for(auto const & spell : CGI->spellh->objects) { bool searchTextFound = !searchBox || boost::algorithm::contains(boost::algorithm::to_lower_copy(spell->getNameTranslated()), boost::algorithm::to_lower_copy(searchBox->getText())); + + if(onSpellSelect) + { + if(spell->isCombat() == openOnBattleSpells && !spell->isSpecial() && !spell->isCreatureAbility()) + mySpells.push_back(spell.get()); + continue; + } + if(!spell->isCreatureAbility() && myHero->canCastThisSpell(spell.get()) && searchTextFound) mySpells.push_back(spell.get()); } @@ -602,6 +612,13 @@ void CSpellWindow::SpellArea::clickPressed(const Point & cursorPosition) { if(mySpell) { + if(owner->onSpellSelect) + { + owner->onSpellSelect(mySpell->id); + owner->fexitb(); + return; + } + auto spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero); if(spellCost > owner->myHero->mana) //insufficient mana { @@ -738,7 +755,7 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell) } ColorRGBA firstLineColor, secondLineColor; - if(spellCost > owner->myHero->mana) //hero cannot cast this spell + if(spellCost > owner->myHero->mana || !owner->onSpellSelect) //hero cannot cast this spell { firstLineColor = Colors::WHITE; secondLineColor = Colors::ORANGE; diff --git a/client/windows/CSpellWindow.h b/client/windows/CSpellWindow.h index 16401a752..f9a761547 100644 --- a/client/windows/CSpellWindow.h +++ b/client/windows/CSpellWindow.h @@ -115,8 +115,11 @@ class CSpellWindow : public CWindowObject std::shared_ptr createBigSpellBook(); + bool openOnBattleSpells; + std::function onSpellSelect; //external processing of selected spell + public: - CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells = true); + CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _myInt, bool openOnBattleSpells = true, std::function onSpellSelect = nullptr); ~CSpellWindow(); void fexitb(); From f0435d8b8e2db7d6e1bb544ae3946857d36b86a6 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:48:00 +0200 Subject: [PATCH 19/22] small fix --- client/battle/BattleInterfaceClasses.cpp | 4 +++- client/battle/BattleInterfaceClasses.h | 2 ++ client/battle/BattleWindow.cpp | 11 +++++++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 516ddceed..1fa9518b7 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -44,6 +44,7 @@ #include "../render/CAnimation.h" #include "../render/IRenderHandler.h" #include "../adventureMap/CInGameConsole.h" +#include "../eventsSDL/InputHandler.h" #include "../../CCallback.h" #include "../../lib/CStack.h" @@ -470,6 +471,7 @@ void QuickSpellPanel::create() }); button->setOverlay(std::make_shared(AnimationPath::builtin("spellint"), !spellIdentifier.empty() ? id.num + 1 : 0)); button->addPopupCallback([this, i, hero](){ + GH.input().hapticFeedback(); GH.windows().createAndPushWindow(hero, owner.curInt.get(), true, [this, i](SpellID spell){ Settings configID = persistentStorage.write["quickSpell"][std::to_string(i)]; configID->String() = spell.toSpell()->identifier; @@ -479,7 +481,7 @@ void QuickSpellPanel::create() if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); + buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); } labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String())); diff --git a/client/battle/BattleInterfaceClasses.h b/client/battle/BattleInterfaceClasses.h index 9cce7143e..d40f04ea4 100644 --- a/client/battle/BattleInterfaceClasses.h +++ b/client/battle/BattleInterfaceClasses.h @@ -160,6 +160,8 @@ private: BattleInterface & owner; public: + bool isEnabled; // isActive() is not working on multiple conditions, because of this we need a seperate flag + QuickSpellPanel(BattleInterface & owner); void create(); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index 67e416502..b60135d51 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -226,6 +226,7 @@ void BattleWindow::hideStickyQuickSpellWindow() showStickyQuickSpellWindow->Bool() = false; quickSpellWindow->disable(); + quickSpellWindow->isEnabled = false; setPositionInfoWindow(); createTimerInfoWindows(); @@ -238,9 +239,15 @@ void BattleWindow::showStickyQuickSpellWindow() showStickyQuickSpellWindow->Bool() = true; if(GH.screenDimensions().x >= 1050) + { quickSpellWindow->enable(); + quickSpellWindow->isEnabled = true; + } else + { quickSpellWindow->disable(); + quickSpellWindow->isEnabled = false; + } setPositionInfoWindow(); createTimerInfoWindows(); @@ -251,7 +258,7 @@ void BattleWindow::createTimerInfoWindows() { OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; - int xOffsetAttacker = quickSpellWindow->isActive() ? -53 : 0; + int xOffsetAttacker = quickSpellWindow->isEnabled ? -53 : 0; if(LOCPLINT->cb->getStartInfo()->turnTimerInfo.battleTimer != 0 || LOCPLINT->cb->getStartInfo()->turnTimerInfo.unitTimer != 0) { @@ -373,7 +380,7 @@ void BattleWindow::updateQueue() void BattleWindow::setPositionInfoWindow() { - int xOffsetAttacker = quickSpellWindow->isActive() ? -53 : 0; + int xOffsetAttacker = quickSpellWindow->isEnabled ? -53 : 0; if(defenderHeroWindow) { Point position = (GH.screenDimensions().x >= 1000) From 2dd22c383b60397d302482743f7f097d5f1c8fd5 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:05:14 +0200 Subject: [PATCH 20/22] make inactive buttons darker --- client/battle/BattleInterfaceClasses.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 1fa9518b7..995146f1c 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -481,7 +481,7 @@ void QuickSpellPanel::create() if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 128))); + buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); } labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String())); From 4415f645a719db514bca357585863631206b41fb Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 18:07:45 +0200 Subject: [PATCH 21/22] lambda -> function; fix color --- client/battle/BattleWindow.cpp | 66 +++++++++++++++++---------------- client/battle/BattleWindow.h | 2 + client/windows/CSpellWindow.cpp | 2 +- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index b60135d51..ecfe285ce 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -64,39 +64,23 @@ BattleWindow::BattleWindow(BattleInterface & Owner): const JsonNode config(JsonPath::builtin("config/widgets/BattleWindow2.json")); - auto useSpellIfPossible = [this](int slot){ - std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(slot)].String(); - SpellID id; - try - { - id = SpellID::decode(spellIdentifier); - } - catch(const IdentifierResolutionException& e) - { - return; - } - if(id.hasValue() && owner.getBattle()->battleGetMyHero() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, owner.getBattle()->battleGetMyHero())) - { - owner.castThisSpell(id); - } - }; addShortcut(EShortcut::BATTLE_TOGGLE_QUICKSPELL, [this](){ this->toggleStickyQuickSpellVisibility();}); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [useSpellIfPossible](){ useSpellIfPossible(0); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [useSpellIfPossible](){ useSpellIfPossible(1); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [useSpellIfPossible](){ useSpellIfPossible(2); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_3, [useSpellIfPossible](){ useSpellIfPossible(3); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_4, [useSpellIfPossible](){ useSpellIfPossible(4); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_5, [useSpellIfPossible](){ useSpellIfPossible(5); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_6, [useSpellIfPossible](){ useSpellIfPossible(6); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [useSpellIfPossible](){ useSpellIfPossible(7); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [useSpellIfPossible](){ useSpellIfPossible(8); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [useSpellIfPossible](){ useSpellIfPossible(9); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_10, [useSpellIfPossible](){ useSpellIfPossible(10); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_11, [useSpellIfPossible](){ useSpellIfPossible(11); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_12, [useSpellIfPossible](){ useSpellIfPossible(12); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_13, [useSpellIfPossible](){ useSpellIfPossible(13); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_14, [useSpellIfPossible](){ useSpellIfPossible(14); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_15, [useSpellIfPossible](){ useSpellIfPossible(15); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_0, [this](){ useSpellIfPossible(0); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_1, [this](){ useSpellIfPossible(1); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_2, [this](){ useSpellIfPossible(2); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_3, [this](){ useSpellIfPossible(3); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_4, [this](){ useSpellIfPossible(4); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_5, [this](){ useSpellIfPossible(5); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_6, [this](){ useSpellIfPossible(6); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_7, [this](){ useSpellIfPossible(7); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_8, [this](){ useSpellIfPossible(8); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [this](){ useSpellIfPossible(9); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_10, [this](){ useSpellIfPossible(10); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_11, [this](){ useSpellIfPossible(11); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_12, [this](){ useSpellIfPossible(12); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_13, [this](){ useSpellIfPossible(13); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_14, [this](){ useSpellIfPossible(14); }); + addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_15, [this](){ useSpellIfPossible(15); }); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); @@ -291,6 +275,24 @@ std::shared_ptr BattleWindow::buildBattleConsole(const JsonNode & return std::make_shared(owner, background, rect.topLeft(), offset, rect.dimensions() ); } +void BattleWindow::useSpellIfPossible(int slot) +{ + std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(slot)].String(); + SpellID id; + try + { + id = SpellID::decode(spellIdentifier); + } + catch(const IdentifierResolutionException& e) + { + return; + } + if(id.hasValue() && owner.getBattle()->battleGetMyHero() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, owner.getBattle()->battleGetMyHero())) + { + owner.castThisSpell(id); + } +}; + void BattleWindow::toggleQueueVisibility() { if(settings["battle"]["showQueue"].Bool()) diff --git a/client/battle/BattleWindow.h b/client/battle/BattleWindow.h index d5b21657a..8292a6301 100644 --- a/client/battle/BattleWindow.h +++ b/client/battle/BattleWindow.h @@ -71,6 +71,8 @@ class BattleWindow : public InterfaceObjectConfigurable PossiblePlayerBattleAction defaultAction; void showAlternativeActionIcon(PossiblePlayerBattleAction); + void useSpellIfPossible(int slot); + /// flip battle queue visibility to opposite void toggleQueueVisibility(); void createQueue(); diff --git a/client/windows/CSpellWindow.cpp b/client/windows/CSpellWindow.cpp index e91cbbada..f20c0e306 100644 --- a/client/windows/CSpellWindow.cpp +++ b/client/windows/CSpellWindow.cpp @@ -755,7 +755,7 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell) } ColorRGBA firstLineColor, secondLineColor; - if(spellCost > owner->myHero->mana || !owner->onSpellSelect) //hero cannot cast this spell + if(spellCost > owner->myHero->mana && !owner->onSpellSelect) //hero cannot cast this spell { firstLineColor = Colors::WHITE; secondLineColor = Colors::ORANGE; From e629b7a371c33b6a68b6b5828e9f79f6c880eb5c Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:26:18 +0200 Subject: [PATCH 22/22] reduce to 12 with gap --- client/battle/BattleInterfaceClasses.cpp | 8 ++++---- client/battle/BattleWindow.cpp | 4 ---- client/gui/Shortcut.h | 4 ---- client/gui/ShortcutHandler.cpp | 4 ---- config/shortcutsConfig.json | 12 ++++-------- 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 995146f1c..9837a071a 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -450,7 +450,7 @@ void QuickSpellPanel::create() if(!hero) return; - for(int i = 0; i < 16; i++) { + for(int i = 0; i < 12; i++) { std::string spellIdentifier = persistentStorage["quickSpell"][std::to_string(i)].String(); SpellID id; @@ -463,7 +463,7 @@ void QuickSpellPanel::create() id = SpellID::NONE; } - auto button = std::make_shared(Point(2, 5 + 37 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ + auto button = std::make_shared(Point(2, 7 + 50 * i), AnimationPath::builtin("spellint"), CButton::tooltip(), [this, id, hero](){ if(id.hasValue() && id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { owner.castThisSpell(id); @@ -481,9 +481,9 @@ void QuickSpellPanel::create() if(!id.hasValue() || !id.toSpell()->canBeCast(owner.getBattle().get(), spells::Mode::HERO, hero)) { - buttonsDisabled.push_back(std::make_shared(Rect(2, 5 + 37 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); + buttonsDisabled.push_back(std::make_shared(Rect(2, 7 + 50 * i, 48, 36), ColorRGBA(0, 0, 0, 172))); } - labels.push_back(std::make_shared(7, 8 + 37 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String())); + labels.push_back(std::make_shared(7, 10 + 50 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String())); buttons.push_back(button); } diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index ecfe285ce..fdc6b7fb7 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -77,10 +77,6 @@ BattleWindow::BattleWindow(BattleInterface & Owner): addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_9, [this](){ useSpellIfPossible(9); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_10, [this](){ useSpellIfPossible(10); }); addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_11, [this](){ useSpellIfPossible(11); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_12, [this](){ useSpellIfPossible(12); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_13, [this](){ useSpellIfPossible(13); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_14, [this](){ useSpellIfPossible(14); }); - addShortcut(EShortcut::BATTLE_SPELL_SHORTCUT_15, [this](){ useSpellIfPossible(15); }); addShortcut(EShortcut::GLOBAL_OPTIONS, std::bind(&BattleWindow::bOptionsf, this)); addShortcut(EShortcut::BATTLE_SURRENDER, std::bind(&BattleWindow::bSurrenderf, this)); diff --git a/client/gui/Shortcut.h b/client/gui/Shortcut.h index 57027fa44..aedf695d9 100644 --- a/client/gui/Shortcut.h +++ b/client/gui/Shortcut.h @@ -199,10 +199,6 @@ enum class EShortcut BATTLE_SPELL_SHORTCUT_9, BATTLE_SPELL_SHORTCUT_10, BATTLE_SPELL_SHORTCUT_11, - BATTLE_SPELL_SHORTCUT_12, - BATTLE_SPELL_SHORTCUT_13, - BATTLE_SPELL_SHORTCUT_14, - BATTLE_SPELL_SHORTCUT_15, MARKET_DEAL, MARKET_MAX_AMOUNT, diff --git a/client/gui/ShortcutHandler.cpp b/client/gui/ShortcutHandler.cpp index 9e6ce0e96..259a1c6cb 100644 --- a/client/gui/ShortcutHandler.cpp +++ b/client/gui/ShortcutHandler.cpp @@ -235,10 +235,6 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const {"battleSpellShortcut9", EShortcut::BATTLE_SPELL_SHORTCUT_9 }, {"battleSpellShortcut10", EShortcut::BATTLE_SPELL_SHORTCUT_10 }, {"battleSpellShortcut11", EShortcut::BATTLE_SPELL_SHORTCUT_11 }, - {"battleSpellShortcut12", EShortcut::BATTLE_SPELL_SHORTCUT_12 }, - {"battleSpellShortcut13", EShortcut::BATTLE_SPELL_SHORTCUT_13 }, - {"battleSpellShortcut14", EShortcut::BATTLE_SPELL_SHORTCUT_14 }, - {"battleSpellShortcut15", EShortcut::BATTLE_SPELL_SHORTCUT_15 }, {"spectateTrackHero", EShortcut::SPECTATE_TRACK_HERO }, {"spectateSkipBattle", EShortcut::SPECTATE_SKIP_BATTLE }, {"spectateSkipBattleResult", EShortcut::SPECTATE_SKIP_BATTLE_RESULT }, diff --git a/config/shortcutsConfig.json b/config/shortcutsConfig.json index caf62161d..fddef65fe 100644 --- a/config/shortcutsConfig.json +++ b/config/shortcutsConfig.json @@ -73,14 +73,10 @@ "battleSpellShortcut5": "6", "battleSpellShortcut6": "7", "battleSpellShortcut7": "8", - "battleSpellShortcut8": "Shift+1", - "battleSpellShortcut9": "Shift+2", - "battleSpellShortcut10": "Shift+3", - "battleSpellShortcut11": "Shift+4", - "battleSpellShortcut12": "Shift+5", - "battleSpellShortcut13": "Shift+6", - "battleSpellShortcut14": "Shift+7", - "battleSpellShortcut15": "Shift+8", + "battleSpellShortcut8": "9", + "battleSpellShortcut9": "0", + "battleSpellShortcut10": "N", + "battleSpellShortcut11": "M", "battleSurrender": "S", "battleTacticsEnd": [ "Return", "Keypad Enter"], "battleTacticsNext": "Space",