mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Start craft failure improvement.
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="72px" height="72px" viewBox="0 0 72 72" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Profile / filled_gift_broken</title>
|
||||
<g id="Profile-/-filled_gift_broken" stroke="none" fill="none" fill-rule="nonzero">
|
||||
<path d="M44.01,42.471 L58.9144129,43.4329741 C59.1317384,43.4469887 59.3445298,43.432761 59.549137,43.3933961 L58.2743575,61.6159362 C57.966154,66.0234515 54.1433086,69.3466003 49.7357933,69.0383968 L34.314,67.96 L46.1422991,46.6629464 L44.01,42.471 Z M32.668,41.027 L32.6158159,41.2978516 L36.4362986,47.0097656 L28.513,67.531 L21.2642067,68.0383968 C16.8566914,68.3466003 13.033846,65.0234515 12.7256425,60.6159362 L11.4595625,42.5101487 L32.668,41.027 Z M52.7544291,6.27336698 C52.9779475,6.39016761 53.1973457,6.514516 53.4126237,6.64641215 C55.0176557,7.62977987 56.2616486,8.92407226 57.1446026,10.5292893 C58.0275565,12.1345064 58.4001354,13.9224034 58.2623393,15.8929805 C58.1684413,17.2357837 57.8224168,18.4521068 57.2242656,19.5419496 C56.6925757,20.5106988 56.0170589,21.3556211 55.197715,22.0767164 L54.947,22.287 L62.9899881,22.8504512 C65.1937457,23.0045529 66.8553201,24.9159756 66.7012184,27.1197333 L66.352436,32.1075535 C66.1983343,34.3113112 64.2869115,35.9728856 62.0831539,35.8187838 L60.0880258,35.6792709 L60.0842427,35.744126 C59.9555848,35.7045582 59.8222579,35.6750041 59.6850985,35.6564261 L59.5214942,35.6396551 L42.96,34.481 L47.4954306,21.4249821 C48.4590745,21.2117744 49.3030651,20.8424669 50.0274024,20.3170595 L50.2466035,20.1503864 C51.6827465,19.0063596 52.4591898,17.5995902 52.5759335,15.9300781 C52.690162,14.296534 52.2359988,12.9791603 51.2134438,11.9779569 C51.1056746,11.872438 50.9940848,11.7718151 50.8786746,11.6760885 L52.7544291,6.27336698 Z M40.1952262,2.97031672 L38.9606472,9.21627213 C38.5526755,9.51211515 38.1719562,9.86109597 37.8184893,10.2632146 C36.6644316,11.5761188 36.5026282,13.2206286 36.6207581,15.2465546 L36.919,19.536 L34.247,33.047 L8.9168461,34.8187838 C6.71308845,34.9728856 4.80166575,33.3113112 4.647564,31.1075535 L4.29878163,26.1197333 C4.14467989,23.9159756 5.80625429,22.0045529 8.01001194,21.8504512 L15.6498801,21.3165167 C14.7171227,20.5507566 13.9584272,19.6352697 13.3737936,18.5700561 C12.7756425,17.4802132 12.429618,16.2638902 12.33572,14.9210869 C12.1979239,12.9505099 12.5705893,11.1626068 13.4537162,9.55737761 C14.3368432,7.95214845 15.5858537,6.65750519 17.2007477,5.67344785 C18.8156417,4.68939051 20.6447641,4.12591933 22.688115,3.98303432 C24.9601966,3.8241549 27.0227818,4.26215829 28.8758706,5.29704452 C30.7289594,6.33193074 32.1218402,7.88166841 33.054513,9.94625754 C33.6907738,7.77195789 34.8493133,6.04380752 36.5301315,4.76180645 C37.6260713,3.92590641 38.8477695,3.32874316 40.1952262,2.97031672 Z M23.5142475,9.32274237 C21.7840605,9.44372884 20.4070839,10.0048661 19.3833178,11.0061541 C18.3595517,12.0074421 17.9047829,13.3248582 18.0190115,14.9584023 C18.1357551,16.6279144 18.9127175,18.0346475 20.3498986,19.1786018 C21.535467,20.1222797 23.0636284,20.6185744 24.9343828,20.6674858 L30.963891,20.2443571 L30.6654633,15.9711247 C30.5218807,13.9177968 29.8222681,12.3001314 28.5666257,11.1181284 L28.3522035,10.9251618 C26.9615898,9.72858813 25.3489378,9.19444833 23.5142475,9.32274237 Z" id="Shape" fill="#FFFFFF"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
@@ -55,7 +55,6 @@
|
||||
<file alias="passkeys.tgs">../../animations/passkeys.tgs</file>
|
||||
<file alias="ban.tgs">../../animations/ban.tgs</file>
|
||||
<file alias="cocoon.tgs">../../animations/cocoon.tgs</file>
|
||||
<file alias="bomb.tgs">../../animations/bomb.tgs</file>
|
||||
|
||||
<file alias="profile_muting.tgs">../../animations/profile/profile_muting.tgs</file>
|
||||
<file alias="profile_unmuting.tgs">../../animations/profile/profile_unmuting.tgs</file>
|
||||
|
||||
@@ -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<CraftFailAnimation> SetupFailureAnimation(
|
||||
not_null<RpWidget*> canvas,
|
||||
not_null<CraftAnimationState*> state) {
|
||||
auto result = std::make_unique<CraftFailAnimation>();
|
||||
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<HistoryView::LottiePlayer>(
|
||||
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<const CraftAnimationState*> state) {
|
||||
const auto animation = state->failureAnimation.get();
|
||||
return animation
|
||||
? animation->scaleAnimation.value(animation->scaleStarted ? 0. : 1.)
|
||||
: 1.;
|
||||
}
|
||||
|
||||
void FailureAnimationCheck(
|
||||
not_null<CraftAnimationState*> state,
|
||||
not_null<RpWidget*> 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<float64> FailureAnimationPrepareFrame(
|
||||
void FailureAnimationPrepareFrame(
|
||||
not_null<CraftAnimationState*> state,
|
||||
not_null<RpWidget*> 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<CraftAnimationState*> state,
|
||||
not_null<RpWidget*> canvas,
|
||||
QPointF center,
|
||||
float64 size) {
|
||||
QPainter &p,
|
||||
not_null<CraftAnimationState*> state,
|
||||
not_null<RpWidget*> 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<void()>();
|
||||
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<QColor>();
|
||||
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<void()> 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<void()> 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();
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ struct CraftState {
|
||||
bool shown = false;
|
||||
};
|
||||
|
||||
std::array<Cover, 4> covers;
|
||||
std::array<Cover, 5> covers; // Last one for failed background.
|
||||
rpl::variable<QColor> 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<EmptySide, 6> forgeSides;
|
||||
EmptySide finalSide;
|
||||
|
||||
Main::Session *session = nullptr;
|
||||
|
||||
@@ -112,7 +112,9 @@ struct CraftState {
|
||||
int craftingHeight,
|
||||
float64 slideProgress = 0.);
|
||||
void updateForGiftCount(int count, Fn<void()> 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<HistoryView::StickerPlayer> 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,11 @@ struct ColorScheme {
|
||||
return QColor(0xBA, 0xDF, 0xFF, 32);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::array<ColorScheme, 4> CraftBackdrops() {
|
||||
[[nodiscard]] QColor ForgeFailOverlay() {
|
||||
return QColor(0xE1, 0x79, 0x23, 41);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::array<ColorScheme, 5> 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)];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user