diff --git a/client/NetPacksLobbyClient.cpp b/client/NetPacksLobbyClient.cpp index 49c86f11d..015fd856f 100644 --- a/client/NetPacksLobbyClient.cpp +++ b/client/NetPacksLobbyClient.cpp @@ -78,7 +78,8 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon GH.windows().popWindows(1); } - GH.windows().createAndPushWindow(handler.screenType); + bool hideScreen = handler.campaignStateToSend && (!handler.campaignStateToSend->campaignSet.empty() || handler.campaignStateToSend->lastScenario()); + GH.windows().createAndPushWindow(handler.screenType, hideScreen); } handler.setState(EClientState::LOBBY); } diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 30f687919..596bdbd1e 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -908,7 +908,7 @@ BattleResultResources BattleResultWindow::getResources(const BattleResult & br) case EBattleResult::SURRENDER: resources.resultText.appendTextID("core.genrltxt.309"); resources.musicName = AudioPath::builtin("Music/Surrender Battle"); - resources.prologueVideo = VideoPath(); + resources.prologueVideo = VideoPath::builtin("SURRENDER.BIK"); resources.loopedVideo = VideoPath::builtin("SURRENDER.BIK"); break; default: diff --git a/client/lobby/CBonusSelection.cpp b/client/lobby/CBonusSelection.cpp index ced7705fd..d6bdd7ba4 100644 --- a/client/lobby/CBonusSelection.cpp +++ b/client/lobby/CBonusSelection.cpp @@ -484,7 +484,7 @@ void CBonusSelection::decreaseDifficulty() } CBonusSelection::CRegion::CRegion(CampaignScenarioID id, bool accessible, bool selectable, bool labelOnly, const CampaignRegions & campDsc) - : CIntObject(LCLICK | SHOW_POPUP), idOfMapAndRegion(id), accessible(accessible), selectable(selectable), labelOnly(labelOnly) + : CIntObject(LCLICK | SHOW_POPUP | TIME), idOfMapAndRegion(id), accessible(accessible), selectable(selectable), labelOnly(labelOnly), blinkAnim({}) { OBJECT_CONSTRUCTION; @@ -509,12 +509,18 @@ CBonusSelection::CRegion::CRegion(CampaignScenarioID id, bool accessible, bool s } } -void CBonusSelection::CRegion::updateState() +void CBonusSelection::CRegion::updateState(bool disableAll) { if(labelOnly) return; - if(!accessible) + if(disableAll) + { + graphicsNotSelected->disable(); + graphicsSelected->disable(); + graphicsStriped->disable(); + } + else if(!accessible) { graphicsNotSelected->disable(); graphicsSelected->disable(); @@ -534,6 +540,29 @@ void CBonusSelection::CRegion::updateState() } } +void CBonusSelection::CRegion::tick(uint32_t msPassed) +{ + if(!accessible) + { + removeUsedEvents(TIME); + return; + } + + blinkAnim.msPassed += msPassed; + if(blinkAnim.msPassed >= 150) + { + blinkAnim.state = !blinkAnim.state; + blinkAnim.msPassed -= 150; + if(blinkAnim.state) + blinkAnim.count++; + else if(blinkAnim.count >= 3) + removeUsedEvents(TIME); + } + updateState(blinkAnim.state); + setRedrawParent(true); + redraw(); +} + void CBonusSelection::CRegion::clickReleased(const Point & cursorPosition) { if(!labelOnly && selectable && !graphicsNotSelected->getSurface()->isTransparent(cursorPosition - pos.topLeft())) diff --git a/client/lobby/CBonusSelection.h b/client/lobby/CBonusSelection.h index 7b26bcc88..8d5b77c15 100644 --- a/client/lobby/CBonusSelection.h +++ b/client/lobby/CBonusSelection.h @@ -51,9 +51,16 @@ public: bool selectable; // true if region should be selectable bool labelOnly; std::shared_ptr label; + struct BlinkAnim + { + uint32_t msPassed; + uint32_t count; + bool state; + } blinkAnim; public: CRegion(CampaignScenarioID id, bool accessible, bool selectable, bool labelOnly, const CampaignRegions & campDsc); - void updateState(); + void updateState(bool disableAll = false); + void tick(uint32_t msPassed) override; void clickReleased(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override; }; diff --git a/client/lobby/CLobbyScreen.cpp b/client/lobby/CLobbyScreen.cpp index ead6f3ef3..adc47a8c5 100644 --- a/client/lobby/CLobbyScreen.cpp +++ b/client/lobby/CLobbyScreen.cpp @@ -21,6 +21,7 @@ #include "../gui/CGuiHandler.h" #include "../gui/Shortcut.h" #include "../widgets/Buttons.h" +#include "../widgets/GraphicalPrimitiveCanvas.h" #include "../windows/InfoWindows.h" #include "../render/Colors.h" #include "../globalLobby/GlobalLobbyClient.h" @@ -35,7 +36,7 @@ #include "../../lib/rmg/CMapGenOptions.h" #include "../CGameInfo.h" -CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) +CLobbyScreen::CLobbyScreen(ESelectionScreen screenType, bool hideScreen) : CSelectionBase(screenType), bonusSel(nullptr) { OBJECT_CONSTRUCTION; @@ -114,6 +115,12 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType) if (wasInLobbyRoom) CSH->getGlobalLobby().activateInterface(); }, EShortcut::GLOBAL_CANCEL); + + if(hideScreen) // workaround to avoid confusing players by custom campaign list displaying for a few ms -> instead of this draw a black screen while "loading" + { + blackScreen = std::make_shared(Rect(Point(0, 0), pos.dimensions())); + blackScreen->addBox(Point(0, 0), pos.dimensions(), Colors::BLACK); + } } CLobbyScreen::~CLobbyScreen() diff --git a/client/lobby/CLobbyScreen.h b/client/lobby/CLobbyScreen.h index db42d9600..d8377b5d8 100644 --- a/client/lobby/CLobbyScreen.h +++ b/client/lobby/CLobbyScreen.h @@ -12,13 +12,15 @@ #include "CSelectionBase.h" class CBonusSelection; +class GraphicalPrimitiveCanvas; class CLobbyScreen final : public CSelectionBase { public: std::shared_ptr buttonChat; + std::shared_ptr blackScreen; - CLobbyScreen(ESelectionScreen type); + CLobbyScreen(ESelectionScreen type, bool hideScreen = false); ~CLobbyScreen(); void toggleTab(std::shared_ptr tab) final; void startCampaign(); diff --git a/lib/bonuses/IBonusBearer.cpp b/lib/bonuses/IBonusBearer.cpp index fa3f8b250..2e6f29d12 100644 --- a/lib/bonuses/IBonusBearer.cpp +++ b/lib/bonuses/IBonusBearer.cpp @@ -59,7 +59,7 @@ TConstBonusListPtr IBonusBearer::getBonusesOfType(BonusType type) const TConstBonusListPtr IBonusBearer::getBonusesOfType(BonusType type, BonusSubtypeID subtype) const { std::string cachingStr = "type_" + std::to_string(static_cast(type)) + "_" + subtype.toString(); - CSelector s = Selector::type()(type); + CSelector s = Selector::typeSubtype(type, subtype); return getBonuses(s, cachingStr); } diff --git a/server/NetPacksLobbyServer.cpp b/server/NetPacksLobbyServer.cpp index 33cc714ff..9e81db3b2 100644 --- a/server/NetPacksLobbyServer.cpp +++ b/server/NetPacksLobbyServer.cpp @@ -170,8 +170,10 @@ void ApplyOnServerNetPackVisitor::visitLobbySetCampaign(LobbySetCampaign & pack) bool isCurrentMapConquerable = pack.ourCampaign->currentScenario() && pack.ourCampaign->isAvailable(*pack.ourCampaign->currentScenario()); - for(auto scenarioID : pack.ourCampaign->allScenarios()) + auto scenarios = pack.ourCampaign->allScenarios(); + for(std::set::reverse_iterator itr = scenarios.rbegin(); itr != scenarios.rend(); itr++) // reverse -> on multiple scenario selection set lowest id at the end { + auto scenarioID = *itr; if(pack.ourCampaign->isAvailable(scenarioID)) { if(!isCurrentMapConquerable || (isCurrentMapConquerable && scenarioID == *pack.ourCampaign->currentScenario()))