From e3adbb469f806071606789a909f1d8daa09d2862 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 28 Jan 2026 11:38:56 +0400 Subject: [PATCH] Start craft failure improvement. --- Telegram/Resources/animations/bomb.tgs | Bin 49236 -> 0 bytes .../icons/chat/filled_forge_fail.svg | 7 + .../Resources/qrc/telegram/animations.qrc | 1 - .../boxes/star_gift_craft_animation.cpp | 274 +++++++----------- .../boxes/star_gift_craft_animation.h | 16 +- .../SourceFiles/boxes/star_gift_craft_box.cpp | 14 +- Telegram/SourceFiles/ui/effects/credits.style | 1 + .../window/window_session_controller.cpp | 2 +- 8 files changed, 135 insertions(+), 180 deletions(-) delete mode 100644 Telegram/Resources/animations/bomb.tgs create mode 100644 Telegram/Resources/icons/chat/filled_forge_fail.svg diff --git a/Telegram/Resources/animations/bomb.tgs b/Telegram/Resources/animations/bomb.tgs deleted file mode 100644 index 62fc72a4e5568d42082452ed8614b41b1b4f7ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49236 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 MABj!+xY8O004Y^O-2eap diff --git a/Telegram/Resources/icons/chat/filled_forge_fail.svg b/Telegram/Resources/icons/chat/filled_forge_fail.svg new file mode 100644 index 0000000000..21ba5796a0 --- /dev/null +++ b/Telegram/Resources/icons/chat/filled_forge_fail.svg @@ -0,0 +1,7 @@ + + + Profile / filled_gift_broken + + + + \ No newline at end of file diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 6b319f4bb5..3902bfff8b 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -55,7 +55,6 @@ ../../animations/passkeys.tgs ../../animations/ban.tgs ../../animations/cocoon.tgs - ../../animations/bomb.tgs ../../animations/profile/profile_muting.tgs ../../animations/profile/profile_unmuting.tgs diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp index 3fa18d9a13..1811dbbe29 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp @@ -42,10 +42,7 @@ constexpr auto kFlightDuration = crl::time(400); constexpr auto kLoadingFadeInDuration = crl::time(150); constexpr auto kLoadingFadeOutDuration = crl::time(300); constexpr auto kLoadingMinDuration = crl::time(600); -constexpr auto kFailurePlayerStopFrame = 120; -constexpr auto kFailurePlayerFps = 60; -constexpr auto kFailurePlayerFadeOutFrames = 10; -constexpr auto kFailureScaleDuration = crl::time(200); +constexpr auto kFailureFadeDuration = crl::time(400); constexpr auto kSuccessFadeInDuration = crl::time(300); constexpr auto kSuccessExpandDuration = crl::time(400); constexpr auto kSuccessExpandStart = crl::time(100); @@ -445,45 +442,9 @@ std::unique_ptr SetupFailureAnimation( not_null canvas, not_null state) { auto result = std::make_unique(); - const auto raw = result.get(); - - const auto document - = raw->document - = ChatHelpers::GenerateLocalTgsSticker( - state->shared->session, - u"bomb"_q); - const auto media = document->createMediaView(); - media->checkStickerLarge(); - - rpl::single() | rpl::then( - document->session().downloaderTaskFinished() - ) | rpl::filter([=] { - return media->loaded(); - }) | rpl::take(1) | rpl::on_next([=] { - const auto sticker = document->sticker(); - Assert(sticker != nullptr); - - const auto size = state->shared->forgeRect.size(); - raw->player = std::make_unique( - ChatHelpers::LottiePlayerFromDocument( - media.get(), - ChatHelpers::StickerLottieSize::InlineResults, - size, - Lottie::Quality::High)); - raw->player->setRepaintCallback([=] { canvas->update(); }); - }, raw->lifetime); - return result; } -[[nodiscard]] float64 FailureAnimationScale( - not_null state) { - const auto animation = state->failureAnimation.get(); - return animation - ? animation->scaleAnimation.value(animation->scaleStarted ? 0. : 1.) - : 1.; -} - void FailureAnimationCheck( not_null state, not_null canvas, @@ -493,23 +454,34 @@ void FailureAnimationCheck( return; } const auto elapsed = (now - state->animationStartTime); - const auto failureDuration = (1000 * kFailurePlayerStopFrame) - / kFailurePlayerFps; - const auto playerStartTime = state->animationDuration - failureDuration; - if (!animation->playerStarted && elapsed >= playerStartTime) { - animation->playerStarted = true; - } - const auto playerScaleStart = state->animationDuration - - kFailureScaleDuration; - if (!animation->scaleStarted && elapsed >= playerScaleStart) { - animation->scaleStarted = true; - animation->scaleAnimation.start([=] { - canvas->update(); - }, 1., 0., kFailureScaleDuration, anim::easeInCubic); + const auto left = (state->animationDuration * Slowing()) - elapsed; + if (!animation->started + && left > 0 + && left <= kFailureFadeDuration * Slowing()) { + animation->started = true; + auto &covers = state->shared->covers; + for (auto i = 0; i != 5; ++i) { + auto &cover = covers[i]; + if (!cover.shown) { + animation->finalCoverIndex = i; + if (i != 4) { + auto &last = covers.back(); + cover.backdrop = last.backdrop; + cover.pattern = std::move(last.pattern); + cover.button1 = last.button1; + cover.button2 = last.button2; + } + cover.shown = true; + cover.shownAnimation.start([=] { + canvas->update(); + }, 0., 1., left); + break; + } + } } } -[[nodiscard]] std::optional FailureAnimationPrepareFrame( +void FailureAnimationPrepareFrame( not_null state, not_null canvas, int faceIndex) { @@ -520,48 +492,35 @@ void FailureAnimationCheck( } const auto shared = state->shared.get(); const auto animation = state->failureAnimation.get(); - if (!animation->player->ready()) { - return {}; - } else if (shared->finalSide.frame.isNull()) { - shared->finalSide = shared->forgeSides[faceIndex]; - shared->finalSide.frame.fill(shared->finalSide.bg); - } if (animation->frame.isNull()) { - animation->frame = shared->finalSide.frame; + animation->frame = shared->forgeSides[faceIndex].frame; } - animation->frame.fill(Qt::transparent); - auto q = QPainter(&animation->frame); - const auto paused = !animation->playerStarted; - auto info = animation->player->frame( - st::giftBoxStickerTiny * 2, - QColor(0, 0, 0, 0), - false, - crl::now(), - paused); - const auto frame = info.image; - const auto finished - = animation->playerFinished - = (info.index + 1 == kFailurePlayerStopFrame); - if (finished) { - return 0.; + const auto lastIndex = animation->finalCoverIndex; + const auto progress = (lastIndex >= 0) + ? shared->covers[lastIndex].shownAnimation.value(1.) + : 0.; + const auto bg = anim::color( + shared->forgeSides[faceIndex].bg, + shared->forgeFail, + progress); + const auto radius = progress * st::boxRadius; + const auto rounded = (radius > 0.); + if (rounded) { + animation->frame.fill(Qt::transparent); } - const auto result = (kFailurePlayerStopFrame - info.index) - / float64(kFailurePlayerFadeOutFrames); - if (!paused) { - animation->player->markFrameShown(); + + auto p = QPainter(&animation->frame); + const auto size = shared->forgeRect.size(); + const auto rect = QRect(QPoint(), size); + if (rounded) { + auto hq = PainterHighQualityEnabler(p); + p.setBrush(bg); + p.setPen(Qt::NoPen); + p.drawRoundedRect(rect, radius, radius); + } else { + p.fillRect(rect, bg); } - const auto outer = animation->frame.size() - / animation->frame.devicePixelRatio(); - const auto size = frame.size() / style::DevicePixelRatio(); - q.drawImage( - QRect( - (outer.width() - size.width()) / 2, - (outer.height() - size.width()) / 2, - size.width(), - size.height()), - frame); - q.end(); - return result; + st::craftFail.paintInCenter(p, rect, st::white->c); } [[nodiscard]] QRect PrepareCraftFrame( @@ -600,29 +559,23 @@ void FailureAnimationCheck( } void PaintCube( - QPainter &p, - not_null state, - not_null canvas, - QPointF center, - float64 size) { + QPainter &p, + not_null state, + not_null canvas, + QPointF center, + float64 size) { const auto shared = state->shared.get(); const auto now = crl::now(); FailureAnimationCheck(state, canvas, now); - const auto totalScale = FailureAnimationScale(state); - const auto showCube = (totalScale > 0.); - const auto scaledCube = showCube && (totalScale < 1.); - if (scaledCube) { - p.save(); - p.translate(center); - p.scale(totalScale, totalScale); - p.translate(-center); - } + const auto success = state->successAnimation.get(); + const auto failure = state->failureAnimation.get(); - const auto faces = GetVisibleCubeFaces( - state->rotationX, - state->rotationY); + const auto finalCoverIndex = failure ? failure->finalCoverIndex : -1; + const auto finishingFailure = (finalCoverIndex >= 0) + ? shared->covers[finalCoverIndex].shownAnimation.value(1.) + : 0.; if (!state->nextFaceRevealed && state->currentPhaseIndex >= 0) { @@ -633,7 +586,9 @@ void PaintCube( } } - const auto craftResult = state->successAnimation.get(); + const auto faces = GetVisibleCubeFaces( + state->rotationX, + state->rotationY); auto paintFailure = Fn(); for (const auto faceIndex : faces) { @@ -668,52 +623,33 @@ void PaintCube( } if (thisFaceRevealed && state->allGiftsLanded) { - const auto coverWidget = craftResult - ? craftResult->widget - : nullptr; - if (coverWidget) { + const auto cover = success ? success->widget : nullptr; + if (cover) { faceSource = PrepareCraftFrame(state, faceIndex, now); - faceImage = craftResult->frame; + faceImage = success->frame; } else { - const auto maybeOpacity = FailureAnimationPrepareFrame( + FailureAnimationPrepareFrame( state, canvas, faceIndex); - if (maybeOpacity) { - if (const auto opacity = *maybeOpacity; opacity > 0.) { - paintFailure = [=, &p] { - if (opacity < 1.) { - p.setOpacity(opacity); - } - PaintCubeFace( - p, - *corners, - state->failureAnimation->frame, - faceSize, - faceSource, - faceRotation); - }; - } - faceImage = shared->finalSide.frame; - } + faceImage = state->failureAnimation->frame; } } - if (showCube) { - PaintCubeFace( - p, - *corners, - faceImage, - faceSize, - faceSource, - faceRotation); + if (finishingFailure > 0.) { + p.setOpacity((faceIndex != state->nextFaceIndex) + ? (1. - finishingFailure) + : 1.); } + PaintCubeFace( + p, + *corners, + faceImage, + faceSize, + faceSource, + faceRotation); } - - if (scaledCube) { - p.restore(); - } - if (paintFailure) { - paintFailure(); + if (finishingFailure > 0.) { + p.setOpacity(1.); } } @@ -1248,7 +1184,7 @@ void CraftState::paint( auto newEdgeColor = std::optional(); auto newButton1 = QColor(); auto newButton2 = QColor(); - for (auto i = 0; i != 4; ++i) { + for (auto i = 0; i != 5; ++i) { auto &cover = covers[i]; if (cover.shownAnimation.animating()) { animating = true; @@ -1286,13 +1222,15 @@ void CraftState::paint( button1 = newButton1; button2 = newButton2; } - if (!animating) { + if (animating) { + p.setOpacity(1.); + } else { coversAnimate = false; } } void CraftState::updateForGiftCount(int count, Fn repaint) { - for (auto i = 4; i != 0;) { + for (auto i = 5; i != 0;) { auto &cover = covers[--i]; const auto shown = (i < count); if (cover.shown != shown) { @@ -1309,7 +1247,9 @@ void CraftState::updateForGiftCount(int count, Fn repaint) { } } -CraftState::EmptySide CraftState::prepareEmptySide(int index) const { +CraftState::EmptySide CraftState::prepareEmptySide( + int index, + bool fail) const { const auto size = forgeRect.size(); const auto ratio = style::DevicePixelRatio(); auto result = QImage(size * ratio, QImage::Format_ARGB32_Premultiplied); @@ -1319,16 +1259,20 @@ CraftState::EmptySide CraftState::prepareEmptySide(int index) const { result.fill(bg); auto p = QPainter(&result); - st::craftForge.paintInCenter(p, QRect(QPoint(), size), st::white->c); + if (fail) { + st::craftFail.paintInCenter(p, QRect(QPoint(), size), st::white->c); + } else { + st::craftForge.paintInCenter(p, QRect(QPoint(), size), st::white->c); + } -#if _DEBUG - p.setFont(st::semiboldFont); - p.setPen(st::white); - p.drawText( - size.width() / 10, - size.width() / 10 + st::semiboldFont->ascent, - QString::number(index)); -#endif // _DEBUG +//#if _DEBUG +// p.setFont(st::semiboldFont); +// p.setPen(st::white); +// p.drawText( +// size.width() / 10, +// size.width() / 10 + st::semiboldFont->ascent, +// QString::number(index)); +//#endif // _DEBUG p.end(); @@ -1376,15 +1320,11 @@ void StartCraftAnimation( st::craftForgeLoading); raw->paintOn([=](QPainter &p) { - if (state->failureAnimation - && state->failureAnimation->playerFinished) { - crl::on_main(closeOnFail); - } - const auto shared = state->shared.get(); const auto success = state->successAnimation.get(); + const auto failure = state->failureAnimation.get(); const auto slideProgress = state->slideOutAnimation.value(1.); - if (slideProgress < 1.) { + if (slideProgress < 1. || (failure && failure->started)) { shared->paint(p, craftingSize, craftingHeight, slideProgress); } else { if (shared->craftBg.isNull()) { @@ -1622,7 +1562,7 @@ void StartCraftAnimation( } } } - if (success->finished) { + if (success && success->finished) { state->continuousAnimation.stop(); raw->hide(); diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h index ac463170b1..82a675e0cc 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h @@ -58,7 +58,7 @@ struct CraftState { bool shown = false; }; - std::array covers; + std::array covers; // Last one for failed background. rpl::variable edgeColor; QColor button1; QColor button2; @@ -89,6 +89,7 @@ struct CraftState { QColor forgeBgOverlay; QColor forgeBg1; QColor forgeBg2; + QColor forgeFail; QImage forgePercent; struct EmptySide { @@ -96,7 +97,6 @@ struct CraftState { QImage frame; }; std::array forgeSides; - EmptySide finalSide; Main::Session *session = nullptr; @@ -112,7 +112,9 @@ struct CraftState { int craftingHeight, float64 slideProgress = 0.); void updateForGiftCount(int count, Fn repaint); - [[nodiscard]] EmptySide prepareEmptySide(int index) const; + [[nodiscard]] EmptySide prepareEmptySide( + int index, + bool fail = false) const; }; struct FacePlacement { @@ -134,13 +136,9 @@ struct CraftDoneAnimation { }; struct CraftFailAnimation { - std::unique_ptr player; QImage frame; - DocumentData *document = nullptr; - Animations::Simple scaleAnimation; - bool scaleStarted = false; - bool playerStarted = false; - bool playerFinished = false; + bool started = false; + int finalCoverIndex = -1; rpl::lifetime lifetime; }; diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp b/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp index 0f7841ba80..dba07751a8 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_craft_box.cpp @@ -56,7 +56,11 @@ struct ColorScheme { return QColor(0xBA, 0xDF, 0xFF, 32); } -[[nodiscard]] std::array CraftBackdrops() { +[[nodiscard]] QColor ForgeFailOverlay() { + return QColor(0xE1, 0x79, 0x23, 41); +} + +[[nodiscard]] std::array CraftBackdrops() { struct Colors { int center = 0; int edge = 0; @@ -84,6 +88,7 @@ struct ColorScheme { hardcoded({ 0x2C4359, 0x232E3F, 0x040C1A, 0x10A5DF, 0x2091E9 }), hardcoded({ 0x2C4359, 0x232E3F, 0x040C1A, 0x10A5DF, 0x2091E9 }), hardcoded({ 0x1C4843, 0x1A2E37, 0x040C1A, 0x3ACA49, 0x007D9E }), + hardcoded({ 0x5D2E16, 0x371B1A, 0x040C1A, 0xE27519, 0xDD4819 }), }; } @@ -504,6 +509,11 @@ AbstractButton *MakeRemoveButton( backdrop.edgeColor, QColor(overlayBg.red(), overlayBg.green(), overlayBg.blue()), overlayBg.alphaF()); + const auto overlayFail = ForgeFailOverlay(); + craftState->forgeFail = anim::color( + CraftBackdrops().back().backdrop.centerColor, + QColor(overlayFail.red(), overlayFail.green(), overlayFail.blue()), + overlayFail.alphaF()); for (auto i = 0; i != 6; ++i) { craftState->forgeSides[i] = craftState->prepareEmptySide(i); } @@ -817,7 +827,7 @@ void Craft( const auto giftsCopy = gifts; base::call_delayed(delay, box, [=] { - const auto shouldSucceed = true;// (base::RandomIndex(5) != 0); + const auto shouldSucceed = false;// (base::RandomIndex(5) != 0); const auto count = int(giftsCopy.size()); if (shouldSucceed && count > 0) { const auto &chosen = giftsCopy[base::RandomIndex(count)]; diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style index dfcff63b99..4706535385 100644 --- a/Telegram/SourceFiles/ui/effects/credits.style +++ b/Telegram/SourceFiles/ui/effects/credits.style @@ -606,6 +606,7 @@ craftPattern: IconEmoji { craftAddIcon: icon {{ "settings/plus", windowFgActive }}; craftPreviewPadding: margins(24px, 12px, 40px, 8px); craftForge: icon{{ "chat/filled_forge-48x48", windowFg }}; +craftFail: icon{{ "chat/filled_forge_fail-48x48", windowFg }}; craftForgePadding: 12px; craftForgePercent: CraftRadialPercent { stroke: 4px; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 15b9317f9b..ab65f6dccd 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1683,7 +1683,7 @@ SessionController::SessionController( }); #if _DEBUG // TEST: Auto-open craft box on startup - constexpr auto kGiftsCount = 1; + constexpr auto kGiftsCount = 4; crl::on_main(this, [=] { if (rand() % 2 < 0) { return;