diff --git a/Mods/vcmi/Data/stackWindow/bonus-effects.png b/Mods/vcmi/Data/stackWindow/bonus-effects.png index aed22ccdf..67fe2ce82 100644 Binary files a/Mods/vcmi/Data/stackWindow/bonus-effects.png and b/Mods/vcmi/Data/stackWindow/bonus-effects.png differ diff --git a/Mods/vcmi/config/english.json b/Mods/vcmi/config/english.json index 2e6af898b..6eb54ea5e 100644 --- a/Mods/vcmi/config/english.json +++ b/Mods/vcmi/config/english.json @@ -28,6 +28,13 @@ "vcmi.adventureMap.movementPointsHeroInfo" : "(Movement points: %REMAINING / %POINTS)", "vcmi.adventureMap.replayOpponentTurnNotImplemented" : "Sorry, replay opponent turn is not implemented yet!", + "vcmi.bonusSource.artifact" : "Artifact", + "vcmi.bonusSource.creature" : "Ability", + "vcmi.bonusSource.spell" : "Spell", + "vcmi.bonusSource.hero" : "Hero", + "vcmi.bonusSource.commander" : "Commander", + "vcmi.bonusSource.other" : "Other", + "vcmi.capitalColors.0" : "Red", "vcmi.capitalColors.1" : "Blue", "vcmi.capitalColors.2" : "Tan", diff --git a/client/widgets/ObjectLists.cpp b/client/widgets/ObjectLists.cpp index d9a257923..6470df4a5 100644 --- a/client/widgets/ObjectLists.cpp +++ b/client/widgets/ObjectLists.cpp @@ -116,12 +116,12 @@ void CListBox::updatePositions() (elem)->moveTo(itemPos); itemPos += itemOffset; } - if (isActive()) + if(slider) { - redraw(); - if (slider) - slider->scrollTo((int)first); + slider->scrollTo((int)first); + moveChildForeground(slider.get()); } + redraw(); } void CListBox::reset() @@ -185,9 +185,6 @@ void CListBox::scrollTo(size_t which) //scroll down else if (first + items.size() <= which && which < totalSize) moveToPos(which - items.size() + 1); - - if(slider) - slider->scrollTo(which); } void CListBox::moveToPos(size_t which) diff --git a/client/windows/CCreatureWindow.cpp b/client/windows/CCreatureWindow.cpp index bae46fc1a..635ac17fc 100644 --- a/client/windows/CCreatureWindow.cpp +++ b/client/windows/CCreatureWindow.cpp @@ -22,6 +22,7 @@ #include "../widgets/Images.h" #include "../widgets/TextControls.h" #include "../widgets/ObjectLists.h" +#include "../widgets/GraphicalPrimitiveCanvas.h" #include "../windows/InfoWindows.h" #include "../gui/CGuiHandler.h" #include "../gui/Shortcut.h" @@ -250,6 +251,47 @@ CStackWindow::BonusLineSection::BonusLineSection(CStackWindow * owner, size_t li Point(214, 4) }; + auto drawBonusSource = [this](int leftRight, Point p, BonusInfo & bi) + { + std::map bonusColors = { + {BonusSource::ARTIFACT, Colors::GREEN}, + {BonusSource::ARTIFACT_INSTANCE, Colors::GREEN}, + {BonusSource::CREATURE_ABILITY, Colors::YELLOW}, + {BonusSource::SPELL_EFFECT, Colors::ORANGE}, + {BonusSource::SECONDARY_SKILL, Colors::PURPLE}, + {BonusSource::HERO_SPECIAL, Colors::PURPLE}, + {BonusSource::STACK_EXPERIENCE, Colors::CYAN}, + {BonusSource::COMMANDER, Colors::CYAN}, + }; + + std::map bonusNames = { + {BonusSource::ARTIFACT, CGI->generaltexth->translate("vcmi.bonusSource.artifact")}, + {BonusSource::ARTIFACT_INSTANCE, CGI->generaltexth->translate("vcmi.bonusSource.artifact")}, + {BonusSource::CREATURE_ABILITY, CGI->generaltexth->translate("vcmi.bonusSource.creature")}, + {BonusSource::SPELL_EFFECT, CGI->generaltexth->translate("vcmi.bonusSource.spell")}, + {BonusSource::SECONDARY_SKILL, CGI->generaltexth->translate("vcmi.bonusSource.hero")}, + {BonusSource::HERO_SPECIAL, CGI->generaltexth->translate("vcmi.bonusSource.hero")}, + {BonusSource::STACK_EXPERIENCE, CGI->generaltexth->translate("vcmi.bonusSource.commander")}, + {BonusSource::COMMANDER, CGI->generaltexth->translate("vcmi.bonusSource.commander")}, + }; + + auto c = bonusColors.count(bi.bonusSource) ? bonusColors[bi.bonusSource] : ColorRGBA(192, 192, 192); + std::string t = bonusNames.count(bi.bonusSource) ? bonusNames[bi.bonusSource] : CGI->generaltexth->translate("vcmi.bonusSource.other"); + int maxLen = 50; + EFonts f = FONT_TINY; + Point pText = p + Point(3, 40); + + // 1px Black border + bonusSource[leftRight].push_back(std::make_shared(pText.x - 1, pText.y, f, ETextAlignment::TOPLEFT, Colors::BLACK, t, maxLen)); + bonusSource[leftRight].push_back(std::make_shared(pText.x + 1, pText.y, f, ETextAlignment::TOPLEFT, Colors::BLACK, t, maxLen)); + bonusSource[leftRight].push_back(std::make_shared(pText.x, pText.y - 1, f, ETextAlignment::TOPLEFT, Colors::BLACK, t, maxLen)); + bonusSource[leftRight].push_back(std::make_shared(pText.x, pText.y + 1, f, ETextAlignment::TOPLEFT, Colors::BLACK, t, maxLen)); + bonusSource[leftRight].push_back(std::make_shared(pText.x, pText.y, f, ETextAlignment::TOPLEFT, c, t, maxLen)); + + frame[leftRight] = std::make_shared(Rect(p.x, p.y, 52, 52)); + frame[leftRight]->addRectangle(Point(0, 0), Point(52, 52), c); + }; + for(size_t leftRight : {0, 1}) { auto position = offset[leftRight]; @@ -259,8 +301,9 @@ CStackWindow::BonusLineSection::BonusLineSection(CStackWindow * owner, size_t li { BonusInfo & bi = parent->activeBonuses[bonusIndex]; icon[leftRight] = std::make_shared(bi.imagePath, position.x, position.y); - name[leftRight] = std::make_shared(position.x + 60, position.y + 2, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, bi.name); - description[leftRight] = std::make_shared(Rect(position.x + 60, position.y + 17, 137, 30), FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, bi.description); + name[leftRight] = std::make_shared(position.x + 60, position.y + 2, FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, bi.name, 137); + description[leftRight] = std::make_shared(Rect(position.x + 60, position.y + 20, 137, 26), FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, bi.description); + drawBonusSource(leftRight, Point(position.x - 1, position.y - 1), bi); } } } @@ -284,7 +327,7 @@ CStackWindow::BonusesSection::BonusesSection(CStackWindow * owner, int yOffset, return std::make_shared(owner, index); }; - lines = std::make_shared(onCreate, Point(0, 0), Point(0, itemHeight), visibleSize, totalSize, 0, 1, Rect(pos.w - 15, 0, pos.h, pos.h)); + lines = std::make_shared(onCreate, Point(0, 0), Point(0, itemHeight), visibleSize, totalSize, 0, totalSize > 3 ? 1 : 0, Rect(pos.w - 15, 0, pos.h, pos.h)); } CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) @@ -533,7 +576,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s animation->setAmount(parent->info->creatureCount); } - name = std::make_shared(215, 12, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, parent->info->getName()); + name = std::make_shared(215, 13, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, parent->info->getName()); const BattleInterface* battleInterface = LOCPLINT->battleInt.get(); const CStack* battleStack = parent->info->stack; @@ -786,6 +829,12 @@ void CStackWindow::initBonusesList() BonusList output; BonusList input; input = *(info->stackNode->getBonuses(CSelector(Bonus::Permanent), Selector::all)); + std::sort(input.begin(), input.end(), [this](std::shared_ptr v1, std::shared_ptr & v2){ + if (v1->source != v2->source) + return v1->source == BonusSource::CREATURE_ABILITY || (v1->source < v2->source); + else + return info->stackNode->bonusToString(v1, false) < info->stackNode->bonusToString(v2, false); + }); while(!input.empty()) { @@ -801,6 +850,7 @@ void CStackWindow::initBonusesList() bonusInfo.name = info->stackNode->bonusToString(b, false); bonusInfo.description = info->stackNode->bonusToString(b, true); bonusInfo.imagePath = info->stackNode->bonusToGraphics(b); + bonusInfo.bonusSource = b->source; //if it's possible to give any description or image for this kind of bonus //TODO: figure out why half of bonuses don't have proper description diff --git a/client/windows/CCreatureWindow.h b/client/windows/CCreatureWindow.h index 62ed20a74..acf43029a 100644 --- a/client/windows/CCreatureWindow.h +++ b/client/windows/CCreatureWindow.h @@ -31,6 +31,7 @@ class CListBox; class CArtPlace; class CCommanderArtPlace; class LRClickableArea; +class GraphicalPrimitiveCanvas; class CCommanderSkillIcon : public LRClickableAreaWText //TODO: maybe bring commander skill button initialization logic inside? { @@ -58,6 +59,7 @@ class CStackWindow : public CWindowObject std::string name; std::string description; ImagePath imagePath; + BonusSource bonusSource; }; class CWindowSection : public CIntObject @@ -84,6 +86,8 @@ class CStackWindow : public CWindowObject std::array, 2> icon; std::array, 2> name; std::array, 2> description; + std::array, 2> frame; + std::array>, 2> bonusSource; public: BonusLineSection(CStackWindow * owner, size_t lineIndex); };