mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #2358 from dydzio0614/persistent-hero-info-window
Add option for persistent hero info window as in HD mod
This commit is contained in:
commit
ddda46a7fd
@ -117,6 +117,8 @@
|
||||
"vcmi.battleOptions.movementHighlightOnHover.help": "{Movement Highlight on Hover}\n\nHighlight unit's movement range when you hover over it.",
|
||||
"vcmi.battleOptions.rangeLimitHighlightOnHover.hover": "Show range limits for shooters",
|
||||
"vcmi.battleOptions.rangeLimitHighlightOnHover.help": "{Show range limits for shooters on Hover}\n\nShow shooter's range limits when you hover over it.",
|
||||
"vcmi.battleOptions.showStickyHeroInfoWindows.hover": "Show heroes statistics windows",
|
||||
"vcmi.battleOptions.showStickyHeroInfoWindows.help": "{Show heroes statistics windows}\n\nPermanently toggle on heroes statistics windows that show primary stats and spell points.",
|
||||
"vcmi.battleOptions.skipBattleIntroMusic.hover": "Skip Intro Music",
|
||||
"vcmi.battleOptions.skipBattleIntroMusic.help": "{Skip Intro Music}\n\nAllow actions during the intro music that plays at the beginning of each battle",
|
||||
"vcmi.battleWindow.pressKeyToSkipIntro" : "Press any key to start battle immediately",
|
||||
|
@ -810,3 +810,10 @@ void BattleInterface::setBattleQueueVisibility(bool visible)
|
||||
if(visible)
|
||||
windowObject->showQueue();
|
||||
}
|
||||
|
||||
void BattleInterface::setStickyHeroWindowsVisibility(bool visible)
|
||||
{
|
||||
windowObject->hideStickyHeroWindows();
|
||||
if(visible)
|
||||
windowObject->showStickyHeroWindows();
|
||||
}
|
||||
|
@ -178,6 +178,7 @@ public:
|
||||
void tacticPhaseEnd();
|
||||
|
||||
void setBattleQueueVisibility(bool visible);
|
||||
void setStickyHeroWindowsVisibility(bool visible);
|
||||
|
||||
void executeStagedAnimations();
|
||||
void executeAnimationStage( EAnimationEvents event);
|
||||
|
@ -296,9 +296,20 @@ void BattleHero::heroLeftClicked()
|
||||
|
||||
void BattleHero::heroRightClicked()
|
||||
{
|
||||
if(settings["battle"]["stickyHeroInfoWindows"].Bool())
|
||||
return;
|
||||
|
||||
Point windowPosition;
|
||||
windowPosition.x = (!defender) ? owner.fieldController->pos.left() + 1 : owner.fieldController->pos.right() - 79;
|
||||
windowPosition.y = owner.fieldController->pos.y + 135;
|
||||
if(GH.screenDimensions().x < 1000)
|
||||
{
|
||||
windowPosition.x = (!defender) ? owner.fieldController->pos.left() + 1 : owner.fieldController->pos.right() - 79;
|
||||
windowPosition.y = owner.fieldController->pos.y + 135;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowPosition.x = (!defender) ? owner.fieldController->pos.left() - 93 : owner.fieldController->pos.right() + 15;
|
||||
windowPosition.y = owner.fieldController->pos.y;
|
||||
}
|
||||
|
||||
InfoAboutHero targetHero;
|
||||
if(owner.makingTurn() || settings["session"]["spectate"].Bool())
|
||||
@ -364,13 +375,19 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
|
||||
addUsedEvents(TIME);
|
||||
}
|
||||
|
||||
HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||
: CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP")
|
||||
HeroInfoBasicPanel::HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground)
|
||||
: CIntObject(0)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
if (position != nullptr)
|
||||
moveTo(*position);
|
||||
background->colorize(hero.owner); //maybe add this functionality to base class?
|
||||
|
||||
if(initializeBackground)
|
||||
{
|
||||
background = std::make_shared<CPicture>("CHRPOP");
|
||||
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
|
||||
background->colorize(hero.owner);
|
||||
}
|
||||
|
||||
auto attack = hero.details->primskills[0];
|
||||
auto defense = hero.details->primskills[1];
|
||||
@ -406,6 +423,24 @@ HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||
labels.push_back(std::make_shared<CLabel>(39, 186, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints)));
|
||||
}
|
||||
|
||||
void HeroInfoBasicPanel::show(Canvas & to)
|
||||
{
|
||||
showAll(to);
|
||||
CIntObject::show(to);
|
||||
}
|
||||
|
||||
HeroInfoWindow::HeroInfoWindow(const InfoAboutHero & hero, Point * position)
|
||||
: CWindowObject(RCLICK_POPUP | SHADOW_DISABLED, "CHRPOP")
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
if (position != nullptr)
|
||||
moveTo(*position);
|
||||
|
||||
background->colorize(hero.owner); //maybe add this functionality to base class?
|
||||
|
||||
content = std::make_shared<HeroInfoBasicPanel>(hero, nullptr, false);
|
||||
}
|
||||
|
||||
BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface & _owner, bool allowReplay)
|
||||
: owner(_owner)
|
||||
{
|
||||
|
@ -127,11 +127,22 @@ public:
|
||||
BattleHero(const BattleInterface & owner, const CGHeroInstance * hero, bool defender);
|
||||
};
|
||||
|
||||
class HeroInfoBasicPanel : public CIntObject //extracted from InfoWindow to fit better as non-popup embed element
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<CPicture> background;
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::vector<std::shared_ptr<CAnimImage>> icons;
|
||||
public:
|
||||
HeroInfoBasicPanel(const InfoAboutHero & hero, Point * position, bool initializeBackground = true);
|
||||
|
||||
void show(Canvas & to) override;
|
||||
};
|
||||
|
||||
class HeroInfoWindow : public CWindowObject
|
||||
{
|
||||
private:
|
||||
std::vector<std::shared_ptr<CLabel>> labels;
|
||||
std::vector<std::shared_ptr<CAnimImage>> icons;
|
||||
std::shared_ptr<HeroInfoBasicPanel> content;
|
||||
public:
|
||||
HeroInfoWindow(const InfoAboutHero & hero, Point * position);
|
||||
};
|
||||
|
@ -67,6 +67,7 @@ BattleWindow::BattleWindow(BattleInterface & owner):
|
||||
addShortcut(EShortcut::BATTLE_SELECT_ACTION, std::bind(&BattleWindow::bSwitchActionf, this));
|
||||
|
||||
addShortcut(EShortcut::BATTLE_TOGGLE_QUEUE, [this](){ this->toggleQueueVisibility();});
|
||||
addShortcut(EShortcut::BATTLE_TOGGLE_HEROES_STATS, [this](){ this->toggleStickyHeroWindowsVisibility();});
|
||||
addShortcut(EShortcut::BATTLE_USE_CREATURE_SPELL, [this](){ this->owner.actionsController->enterCreatureCastingMode(); });
|
||||
addShortcut(EShortcut::GLOBAL_CANCEL, [this](){ this->owner.actionsController->endCastingSpell(); });
|
||||
|
||||
@ -80,6 +81,7 @@ BattleWindow::BattleWindow(BattleInterface & owner):
|
||||
owner.fieldController->createHeroes();
|
||||
|
||||
createQueue();
|
||||
createStickyHeroInfoWindows();
|
||||
|
||||
if ( owner.tacticsMode )
|
||||
tacticPhaseStarted();
|
||||
@ -116,6 +118,41 @@ void BattleWindow::createQueue()
|
||||
queue->disable();
|
||||
}
|
||||
|
||||
void BattleWindow::createStickyHeroInfoWindows()
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
if(owner.defendingHeroInstance)
|
||||
{
|
||||
InfoAboutHero info;
|
||||
info.initFromHero(owner.defendingHeroInstance, InfoAboutHero::EInfoLevel::INBATTLE);
|
||||
Point position = (GH.screenDimensions().x >= 1000)
|
||||
? Point(pos.x + pos.w + 15, pos.y)
|
||||
: Point(pos.x + pos.w -79, pos.y + 135);
|
||||
defenderHeroWindow = std::make_shared<HeroInfoBasicPanel>(info, &position);
|
||||
}
|
||||
if(owner.attackingHeroInstance)
|
||||
{
|
||||
InfoAboutHero info;
|
||||
info.initFromHero(owner.attackingHeroInstance, InfoAboutHero::EInfoLevel::INBATTLE);
|
||||
Point position = (GH.screenDimensions().x >= 1000)
|
||||
? Point(pos.x - 93, pos.y)
|
||||
: Point(pos.x + 1, pos.y + 135);
|
||||
attackerHeroWindow = std::make_shared<HeroInfoBasicPanel>(info, &position);
|
||||
}
|
||||
|
||||
bool showInfoWindows = settings["battle"]["stickyHeroInfoWindows"].Bool();
|
||||
|
||||
if(!showInfoWindows)
|
||||
{
|
||||
if(attackerHeroWindow)
|
||||
attackerHeroWindow->disable();
|
||||
|
||||
if(defenderHeroWindow)
|
||||
defenderHeroWindow->disable();
|
||||
}
|
||||
}
|
||||
|
||||
BattleWindow::~BattleWindow()
|
||||
{
|
||||
CPlayerInterface::battleInt = nullptr;
|
||||
@ -170,6 +207,44 @@ void BattleWindow::showQueue()
|
||||
GH.windows().totalRedraw();
|
||||
}
|
||||
|
||||
void BattleWindow::toggleStickyHeroWindowsVisibility()
|
||||
{
|
||||
if(settings["battle"]["stickyHeroInfoWindows"].Bool())
|
||||
hideStickyHeroWindows();
|
||||
else
|
||||
showStickyHeroWindows();
|
||||
}
|
||||
|
||||
void BattleWindow::hideStickyHeroWindows()
|
||||
{
|
||||
if(settings["battle"]["stickyHeroInfoWindows"].Bool() == false)
|
||||
return;
|
||||
|
||||
Settings showStickyHeroInfoWindows = settings.write["battle"]["stickyHeroInfoWindows"];
|
||||
showStickyHeroInfoWindows->Bool() = false;
|
||||
|
||||
if(attackerHeroWindow)
|
||||
attackerHeroWindow->disable();
|
||||
|
||||
if(defenderHeroWindow)
|
||||
defenderHeroWindow->disable();
|
||||
|
||||
GH.windows().totalRedraw();
|
||||
}
|
||||
|
||||
void BattleWindow::showStickyHeroWindows()
|
||||
{
|
||||
if(settings["battle"]["stickyHeroInfoWindows"].Bool() == true)
|
||||
return;
|
||||
|
||||
Settings showStickyHeroInfoWIndows = settings.write["battle"]["stickyHeroInfoWindows"];
|
||||
showStickyHeroInfoWIndows->Bool() = true;
|
||||
|
||||
|
||||
createStickyHeroInfoWindows();
|
||||
GH.windows().totalRedraw();
|
||||
}
|
||||
|
||||
void BattleWindow::updateQueue()
|
||||
{
|
||||
queue->update();
|
||||
|
@ -24,6 +24,7 @@ class BattleInterface;
|
||||
class BattleConsole;
|
||||
class BattleRenderer;
|
||||
class StackQueue;
|
||||
class HeroInfoBasicPanel;
|
||||
|
||||
/// GUI object that handles functionality of panel at the bottom of combat screen
|
||||
class BattleWindow : public InterfaceObjectConfigurable
|
||||
@ -32,6 +33,8 @@ class BattleWindow : public InterfaceObjectConfigurable
|
||||
|
||||
std::shared_ptr<StackQueue> queue;
|
||||
std::shared_ptr<BattleConsole> console;
|
||||
std::shared_ptr<HeroInfoBasicPanel> attackerHeroWindow;
|
||||
std::shared_ptr<HeroInfoBasicPanel> defenderHeroWindow;
|
||||
|
||||
/// button press handling functions
|
||||
void bOptionsf();
|
||||
@ -60,6 +63,9 @@ class BattleWindow : public InterfaceObjectConfigurable
|
||||
void toggleQueueVisibility();
|
||||
void createQueue();
|
||||
|
||||
void toggleStickyHeroWindowsVisibility();
|
||||
void createStickyHeroInfoWindows();
|
||||
|
||||
std::shared_ptr<BattleConsole> buildBattleConsole(const JsonNode &) const;
|
||||
|
||||
public:
|
||||
@ -73,6 +79,9 @@ public:
|
||||
void hideQueue();
|
||||
void showQueue();
|
||||
|
||||
void hideStickyHeroWindows();
|
||||
void showStickyHeroWindows();
|
||||
|
||||
/// block all UI elements when player is not allowed to act, e.g. during enemy turn
|
||||
void blockUI(bool on);
|
||||
|
||||
|
@ -133,6 +133,7 @@ enum class EShortcut
|
||||
BATTLE_TACTICS_NEXT,
|
||||
BATTLE_TACTICS_END,
|
||||
BATTLE_SELECT_ACTION, // Alternative actions toggle
|
||||
BATTLE_TOGGLE_HEROES_STATS,
|
||||
|
||||
// Town screen
|
||||
TOWN_OPEN_TAVERN,
|
||||
|
@ -134,6 +134,7 @@ std::vector<EShortcut> ShortcutHandler::translateKeycode(SDL_Keycode key) const
|
||||
{SDLK_RETURN, EShortcut::BATTLE_TACTICS_END },
|
||||
{SDLK_KP_ENTER, EShortcut::BATTLE_TACTICS_END },
|
||||
{SDLK_s, EShortcut::BATTLE_SELECT_ACTION },
|
||||
{SDLK_i, EShortcut::BATTLE_TOGGLE_HEROES_STATS},
|
||||
{SDLK_t, EShortcut::TOWN_OPEN_TAVERN },
|
||||
{SDLK_SPACE, EShortcut::TOWN_SWAP_ARMIES },
|
||||
{SDLK_END, EShortcut::RECRUITMENT_MAX },
|
||||
|
@ -60,6 +60,10 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner)
|
||||
{
|
||||
skipBattleIntroMusicChangedCallback(value);
|
||||
});
|
||||
addCallback("showStickyHeroWindowsChanged", [this, owner](bool value)
|
||||
{
|
||||
showStickyHeroWindowsChangedCallback(value, owner);
|
||||
});
|
||||
build(config);
|
||||
|
||||
std::shared_ptr<CToggleGroup> animationSpeedToggle = widget<CToggleGroup>("animationSpeedPicker");
|
||||
@ -80,6 +84,9 @@ BattleOptionsTab::BattleOptionsTab(BattleInterface * owner)
|
||||
std::shared_ptr<CToggleButton> rangeLimitHighlightOnHoverCheckbox = widget<CToggleButton>("rangeLimitHighlightOnHoverCheckbox");
|
||||
rangeLimitHighlightOnHoverCheckbox->setSelected(settings["battle"]["rangeLimitHighlightOnHover"].Bool());
|
||||
|
||||
std::shared_ptr<CToggleButton> showStickyHeroInfoWindowsCheckbox = widget<CToggleButton>("showStickyHeroInfoWindowsCheckbox");
|
||||
showStickyHeroInfoWindowsCheckbox->setSelected(settings["battle"]["stickyHeroInfoWindows"].Bool());
|
||||
|
||||
std::shared_ptr<CToggleButton> mouseShadowCheckbox = widget<CToggleButton>("mouseShadowCheckbox");
|
||||
mouseShadowCheckbox->setSelected(settings["battle"]["mouseShadow"].Bool());
|
||||
|
||||
@ -194,6 +201,19 @@ void BattleOptionsTab::showQueueChangedCallback(bool value, BattleInterface * pa
|
||||
}
|
||||
}
|
||||
|
||||
void BattleOptionsTab::showStickyHeroWindowsChangedCallback(bool value, BattleInterface * parentBattleInterface)
|
||||
{
|
||||
if(!parentBattleInterface)
|
||||
{
|
||||
Settings showStickyWindows = settings.write["battle"]["stickyHeroInfoWindows"];
|
||||
showStickyWindows->Bool() = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentBattleInterface->setStickyHeroWindowsVisibility(value);
|
||||
}
|
||||
}
|
||||
|
||||
void BattleOptionsTab::queueSizeChangedCallback(int value, BattleInterface * parentBattleInterface)
|
||||
{
|
||||
if (value == -1)
|
||||
|
@ -31,6 +31,7 @@ private:
|
||||
void showQueueChangedCallback(bool value, BattleInterface * parentBattleInterface);
|
||||
void queueSizeChangedCallback(int value, BattleInterface * parentBattleInterface);
|
||||
void skipBattleIntroMusicChangedCallback(bool value);
|
||||
void showStickyHeroWindowsChangedCallback(bool value, BattleInterface * parentBattleInterface);
|
||||
public:
|
||||
BattleOptionsTab(BattleInterface * owner = nullptr);
|
||||
};
|
||||
|
@ -262,7 +262,7 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "movementHighlightOnHover", "rangeLimitHighlightOnHover", "showQueue", "swipeAttackDistance", "queueSize" ],
|
||||
"required" : [ "speedFactor", "mouseShadow", "cellBorders", "stackRange", "movementHighlightOnHover", "rangeLimitHighlightOnHover", "showQueue", "swipeAttackDistance", "queueSize", "stickyHeroInfoWindows" ],
|
||||
"properties" : {
|
||||
"speedFactor" : {
|
||||
"type" : "number",
|
||||
@ -300,6 +300,10 @@
|
||||
"type" : "string",
|
||||
"default" : "auto",
|
||||
"enum" : [ "auto", "small", "big" ]
|
||||
},
|
||||
"stickyHeroInfoWindows" : {
|
||||
"type" : "boolean",
|
||||
"default" : true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -110,6 +110,9 @@
|
||||
{
|
||||
"text": "vcmi.battleOptions.rangeLimitHighlightOnHover.hover",
|
||||
},
|
||||
{
|
||||
"text": "vcmi.battleOptions.showStickyHeroInfoWindows.hover",
|
||||
},
|
||||
{
|
||||
"text": "core.genrltxt.406",
|
||||
},
|
||||
@ -144,6 +147,11 @@
|
||||
"help": "vcmi.battleOptions.rangeLimitHighlightOnHover",
|
||||
"callback": "rangeLimitHighlightOnHoverChanged"
|
||||
},
|
||||
{
|
||||
"name": "showStickyHeroInfoWindowsCheckbox",
|
||||
"help": "vcmi.battleOptions.showStickyHeroInfoWindows",
|
||||
"callback": "showStickyHeroWindowsChanged"
|
||||
},
|
||||
{
|
||||
"name": "mouseShadowCheckbox",
|
||||
"help": "core.help.429",
|
||||
|
Loading…
Reference in New Issue
Block a user