diff --git a/src/functions/wish.js b/src/functions/wish.js index d9514a1c..f8e81ad3 100644 --- a/src/functions/wish.js +++ b/src/functions/wish.js @@ -224,8 +224,6 @@ export async function process(id) { } } - if (newPull.id === 'raiden_shogun') console.log(newPull); - if (newPull.rarity > 3) { if (selectedBanners[currentBannerIndex].constellation[newPull.id] === undefined) { selectedBanners[currentBannerIndex].constellation[newPull.id] = 0; @@ -265,7 +263,8 @@ export async function process(id) { currentPulls.push(newPull); } - console.log(constellation); + rateOffLegendary.maxStreak = Math.max(rateOffLegendary.maxStreak, rateOffLegendary.currentStreak); + rateOffRare.maxStreak = Math.max(rateOffRare.maxStreak, rateOffRare.currentStreak); return { pulls: currentPulls, diff --git a/src/routes/settings/_importExportModal.svelte b/src/routes/settings/_importExportModal.svelte index 84b930b6..512b0491 100644 --- a/src/routes/settings/_importExportModal.svelte +++ b/src/routes/settings/_importExportModal.svelte @@ -33,6 +33,7 @@ reader.onload = async () => { try { const data = JSON.parse(reader.result); + await localforage.clear(); for (const key in data) { await updateSave(key, data[key], true); } diff --git a/src/routes/wish/_rank.svelte b/src/routes/wish/_rank.svelte index a7342c0c..4ac40f09 100644 --- a/src/routes/wish/_rank.svelte +++ b/src/routes/wish/_rank.svelte @@ -34,6 +34,8 @@ median = '...'; wishCount = wishTotal[current]; + if (wishCount === 0) return; + try { const url = new URL(`${__paimon.env.API_HOST}/wish/summary`); const query = new URLSearchParams({ banner: current }); @@ -81,6 +83,8 @@ percentageLuck[rarity] = 0; medianLuck[rarity] = '...'; + if (percentages[current] === undefined) return; + try { const url = new URL(`${__paimon.env.API_HOST}/wish/summary/luck`); const query = new URLSearchParams({ banner: current, rarity }); diff --git a/src/routes/wish/_summary.svelte b/src/routes/wish/_summary.svelte index 8a5e1393..a63d867e 100644 --- a/src/routes/wish/_summary.svelte +++ b/src/routes/wish/_summary.svelte @@ -25,6 +25,7 @@ let loading = true; let wishCount = 0; + let box = [0, 1, 2, 3]; const avg = {}; const percentages = {}; @@ -171,7 +172,7 @@ legendaryPity += pull.pity; currentMonthlyData[time].legendary++; - legendaryPulls.push({ name: itemName, pity: pull.pity }); + legendaryPulls.push({ name: itemName, pity: pull.pity, rate: pull.rate }); } else if (rarity === 4) { rare++; rarePity += pull.pity; @@ -211,6 +212,23 @@ }, }; + if (counterData.rateoff !== undefined) { + if (avg[type.id].rare.total > 0) { + avg[type.id].rare.rateOff = { + total: counterData.rateoff.rare.win, + percentage: counterData.rateoff.rare.win / (counterData.rateoff.rare.win + counterData.rateoff.rare.lose), + }; + } + if (avg[type.id].legendary.total > 0) { + avg[type.id].legendary.rateOff = { + total: counterData.rateoff.legendary.win, + percentage: + counterData.rateoff.legendary.win / + (counterData.rateoff.legendary.win + counterData.rateoff.legendary.lose), + }; + } + } + percentages[type.id] = { legendary: avg[type.id].legendary.percentage, rare: avg[type.id].rare.percentage, @@ -221,6 +239,14 @@ wishCount = totalWish; monthlyData = currentMonthlyData; + if ( + avg['weapon-event'] !== undefined && + avg['standard'] !== undefined && + avg['weapon-event'].legendary.total > avg['standard'].legendary.total + ) { + box = [0, 2, 1, 3]; + } + if (updateCollectedCharacters && totalWish > 0) { console.log('updating collectables'); await updateSave(`${prefix}characters`, collectedCharacters); @@ -236,21 +262,21 @@ {#if !loading}
- {#if avg[types[0].id]} - + {#if avg[types[box[0]].id]} + {/if} - {#if avg[types[2].id]} - + {#if avg[types[box[1]].id]} + {/if} - {#if avg[types[1].id]} - + {#if avg[types[box[2]].id]} + {/if}
- {#if avg[types[3].id]} - + {#if avg[types[box[3]].id]} +
{/if} -
+
{$t('wish.wishesWorth')} primogem {numberFormat.format(wishCount * 160)} @@ -281,4 +307,14 @@ column-gap: 1rem; } } + + @screen md { + .summary-item { + margin: 0; + display: grid; + grid-template-rows: 1fr auto; + margin-bottom: 1rem; + break-inside: avoid; + } + } diff --git a/src/routes/wish/_summaryItem.svelte b/src/routes/wish/_summaryItem.svelte index 923ac5eb..61091e7f 100644 --- a/src/routes/wish/_summaryItem.svelte +++ b/src/routes/wish/_summaryItem.svelte @@ -7,7 +7,7 @@ export let avg; export let type; export let order = 0; - export let legendaryPity = 90; + export let legendaryPity = type.id === 'weapon-event' ? 80 : 90; export let colorMultiplier = 120; let numberFormat = Intl.NumberFormat('en', { @@ -48,6 +48,20 @@ {numberFormat.format(avg.legendary.pity)} + {#if avg.legendary.rateOff !== undefined} + + + └ Win 50:50 + + + {numberFormat.format(avg.legendary.rateOff.total)} + + + {numberFormat.format(avg.legendary.rateOff.percentage * 100)}% + + + + {/if} 4 @@ -86,11 +100,23 @@ {numberFormat.format(avg.rare.weapon.pity)} + {#if avg.rare.rateOff !== undefined} + + └ Win 50:50 + + {numberFormat.format(avg.rare.rateOff.total)} + + + {numberFormat.format(avg.rare.rateOff.percentage * 100)}% + + + + {/if} {#if avg.legendary.pulls.length > 0}
{#each avg.legendary.pulls as pull} - {$t(pull.name)} {pull.pity} @@ -110,6 +136,11 @@ @apply mb-1; @apply mr-1; + &.rate-0, + &.rate-2 { + @apply border-gray-500; + } + & > span { @apply font-semibold; @apply pl-1; diff --git a/src/routes/wish/import.svelte b/src/routes/wish/import.svelte index 7a7875d5..4ffa5d99 100644 --- a/src/routes/wish/import.svelte +++ b/src/routes/wish/import.svelte @@ -119,6 +119,12 @@ let error = ''; let bannerList = []; + let currentSelectedBanner = null; + let currentBannerIndex = -1; + let lastBannerIndex; + let lastBanner; + let rateUp = false; + let rateUpRare = false; let wishes = {}; @@ -405,6 +411,7 @@ const path = `wish-counter-${type.id}`; const localData = await readSave(`${prefix}${path}`); + const withRate = type.id === 'character-event' || type.id === 'weapon-event'; let localWishes = []; if (localData !== null) { @@ -417,6 +424,29 @@ localWishes = localWishes.slice().filter((e) => dayjs(e.time).isBefore(dayjs(oldestWish.time))); + currentBanner = null; + currentSelectedBanner = null; + currentBannerIndex = -1; + lastBannerIndex = undefined; + lastBanner = undefined; + rateUp = false; + rateUpRare = false; + + let rateOffLegendary = { + win: 0, + lose: 0, + maxStreak: 0, + currentStreak: 0, + }; + let rateOffRare = { + win: 0, + lose: 0, + maxStreak: 0, + currentStreak: 0, + }; + + if (withRate) processBannerList(type.id); + const combined = [...localWishes, ...importedWishes]; let latestLegendary = null; @@ -435,12 +465,66 @@ rarity = weaponList[combined[i].id].rarity; } + const unixTime = dayjs(combined[i].time).unix(); + if (withRate && (currentSelectedBanner === null || currentSelectedBanner.end < unixTime)) { + lastBannerIndex = currentBannerIndex; + + const nextBanner = getNextBanner(unixTime); + + if (nextBanner === undefined) { + currentBannerIndex = lastBannerIndex; + currentSelectedBanner = lastBanner; + } else { + currentSelectedBanner = nextBanner.selectedBanner; + currentBannerIndex = nextBanner.currentBannerIndex; + lastBanner = currentSelectedBanner; + } + } + + // guaranteed + winrateoff + // f + f = 0 = los 50:50 + // f + t = 1 = win 50:50 + // t + t = 2 = guaranteed + if (rarity === 5) { + if (withRate) { + const guaranteed = rateUp; + const winRateOff = currentSelectedBanner.featured.includes(combined[i].id); + rateUp = !winRateOff; + combined[i].rate = guaranteed + winRateOff; + console.log(combined[i], guaranteed, winRateOff, currentSelectedBanner); + + if (rateUp) { + rateOffLegendary.lose++; + rateOffLegendary.maxStreak = Math.max(rateOffLegendary.maxStreak, rateOffLegendary.currentStreak); + rateOffLegendary.currentStreak = 0; + } else if (!guaranteed) { + rateOffLegendary.win++; + rateOffLegendary.currentStreak++; + } + } + latestLegendary = combined[i]; combined[i].pity = legendary; legendary = 0; // rare = 0; } else if (rarity === 4) { + if (withRate) { + const guaranteed = rateUpRare; + const winRateOff = currentSelectedBanner.featuredRare.includes(combined[i].id); + rateUpRare = !winRateOff; + combined[i].rate = guaranteed + winRateOff; + + if (rateUpRare) { + rateOffRare.lose++; + rateOffRare.maxStreak = Math.max(rateOffRare.maxStreak, rateOffRare.currentStreak); + rateOffRare.currentStreak = 0; + } else if (!guaranteed) { + rateOffRare.win++; + rateOffRare.currentStreak++; + } + } + latestRare = combined[i]; combined[i].pity = rare; rare = 0; @@ -449,39 +533,38 @@ } } - let rateUpLegendary = false; - let rateUpRare = false; - if (type.id === 'character-event' || type.id === 'weapon-event') { - processBannerList(type.id); - - if (latestLegendary !== null) { - const itemBanner = getBannerByTime(latestLegendary.time); - console.log(latestLegendary.time, itemBanner); - if (itemBanner && itemBanner.featured) { - rateUpLegendary = !itemBanner.featured.includes(latestLegendary.id); - } - } - - if (latestRare !== null) { - const itemBanner = getBannerByTime(latestRare.time); - console.log(latestRare.time, itemBanner); - if (itemBanner && itemBanner.featured) { - rateUpRare = !itemBanner.featuredRare.includes(latestRare.id); - } - } - } - const data = { total: combined.length, legendary, rare, pulls: combined, - guaranteed: { - legendary: rateUpLegendary, - rare: rateUpRare, - }, }; + if (withRate) { + let rateUp5 = false; + let rateUp4 = false; + if (latestLegendary !== null) { + rateUp5 = latestLegendary.rate === 0; + } + + if (latestRare !== null) { + rateUp4 = latestRare.rate === 0; + } + + rateOffLegendary.maxStreak = Math.max(rateOffLegendary.maxStreak, rateOffLegendary.currentStreak); + rateOffRare.maxStreak = Math.max(rateOffRare.maxStreak, rateOffRare.currentStreak); + + data.guaranteed = { + legendary: rateUp5, + rare: rateUp4, + }; + + data.rateoff = { + legendary: rateOffLegendary, + rare: rateOffRare, + }; + } + await updateSave(`${prefix}${path}`, data); } @@ -718,11 +801,10 @@ }); } - function getBannerByTime(time) { - const unixTime = dayjs(time).unix(); - for (let i = bannerList.length - 1; i >= 0; i--) { - if (unixTime >= bannerList[i].start && unixTime < bannerList[i].end) { - return bannerList[i]; + function getNextBanner(time) { + for (let i = currentBannerIndex + 1; i < bannerList.length; i++) { + if (time >= bannerList[i].start && time < bannerList[i].end) { + return { currentBannerIndex: i, selectedBanner: bannerList[i] }; } } } diff --git a/src/routes/wish/index.svelte b/src/routes/wish/index.svelte index 919e0858..4727421a 100644 --- a/src/routes/wish/index.svelte +++ b/src/routes/wish/index.svelte @@ -195,7 +195,7 @@
-
+
setRankWishTotal('character-event', val)} bind:this={counter1} @@ -225,7 +225,11 @@ id="beginners" name={$t('wish.types.beginners')} /> - + {#if Object.keys(monthlyData).length > 0} + + {:else} +
+ {/if}