Add chronicled wish

pull/30/head
Made Baruna 2024-03-13 15:46:18 +08:00
parent 5c21dc8b08
commit d3e68c22f3
15 changed files with 189 additions and 124 deletions

View File

@ -15,4 +15,8 @@ export const bannerTypes = [
name: "Beginners' Wish",
id: 'beginners',
},
{
name: 'Chronicled Wish',
id: 'chronicled',
},
];

View File

@ -1904,4 +1904,71 @@ export const banners = {
timezoneDependent: true,
},
],
chronicled: [
{
name: 'Ode to the Dawn Breeze',
image: 1,
shortName: 'Mondstadt',
start: '2024-03-13 06:00:00',
end: '2024-04-02 17:59:00',
color: '#eee8e1',
featured: [
'eula',
'mona',
'albedo',
'klee',
'diluc',
'jean',
'skyward_blade',
'aquila_favonia',
'beacon_of_the_reed_sea',
'song_of_broken_pines',
'wolfs_gravestone',
'skyward_pride',
'skyward_spine',
'lost_prayer_to_the_sacred_winds',
'skyward_atlas',
'hunters_path',
'skyward_harp',
],
featuredRare: [
'mika',
'rosaria',
'sucrose',
'diona',
'noelle',
'bennett',
'fischl',
'amber',
'razor',
'kaeya',
'barbara',
'lisa',
'the_alley_flash',
'lions_roar',
'sacrificial_sword',
'the_flute',
'favonius_sword',
'rainslasher',
'sacrificial_greatsword',
'the_bell',
'favonius_greatsword',
'favonius_lance',
'dragons_bane',
'wine_and_song',
'eye_of_perception',
'sacrificial_fragments',
'the_widsith',
'favonius_codex',
'mitternachts_waltz',
'alley_hunter',
'rust',
'sacrificial_bow',
'the_stringless',
'favonius_warbow',
],
version: '4.5',
timezoneDependent: true,
},
],
};

View File

@ -17,6 +17,7 @@ const bannerTypes = {
'weapon-event': 'weapons',
standard: 'standard',
beginners: 'beginners',
chronicled: 'chronicled',
};
async function readLocalData(path) {

View File

@ -3,7 +3,7 @@ import { getAccountPrefix } from '../stores/account';
import { readSave } from '../stores/saveManager';
import { process } from './wish';
const bannerCategories = ['beginners', 'standard', 'character-event', 'weapon-event'];
const bannerCategories = ['beginners', 'standard', 'character-event', 'weapon-event', 'chronicled'];
async function sendWish(data) {
try {

View File

@ -143,10 +143,7 @@
"manualButton": "Enable Manual Input",
"errorBanner": "Banner time mismatch! Please adjust your server on the settings page. Still not working? Please leave a message on Discord 😅",
"globalWishTally": "Global Wish Stats",
"pityTooltip": [
"Shows your current {rarity} pity",
"{count} pulls to guaranteed {rarity}"
],
"pityTooltip": ["Shows your current {rarity} pity", "{count} pulls to guaranteed {rarity}"],
"import": {
"title": "Import Wish History",
"faqsButton": "FAQ - READ FIRST",
@ -182,11 +179,7 @@
"server": "Select your server:",
"wishTallyCheck": "Submit pity for global wish stats",
"wishTally": "We are doing a global wish stats! You can submit your wish stats to participate. All pity data will be aggregated to know what is the average pity of paimon.moe users.",
"wishTallyCollected": [
"What will be collected:",
"and",
"pity from your wish history"
],
"wishTallyCollected": ["What will be collected:", "and", "pity from your wish history"],
"forceUpdateCheck": "Force update wish history (enable only if your wish history is not updating)",
"header": [
"Import and backup your Genshin Impact wish history to keep it for more than 6 months. It also automatically tracks your pity and statistics about your wishes!",
@ -396,11 +389,7 @@
"exportFinish": "Export success, please wait until your browser downloads the file!",
"wishTallyTitle": "Submit Wish Stats",
"wishTally": "We are doing a global wish stats! You can submit your wish stats to participate. All pity data will be aggregated to know what is the average pity of paimon.moe users.",
"wishTallyCollected": [
"What will be collected:",
"and",
"pity from your wish history"
],
"wishTallyCollected": ["What will be collected:", "and", "pity from your wish history"],
"wishTallySubmit": "Submit Wish Stats",
"wishTallyThankyou": "Thank you for participating!",
"manualTitle": "Manual Input Settings",
@ -412,22 +401,13 @@
"subtitle": "After a 1x Wish:",
"pressWhenYouGet": "Press {button} when you get {rarity}★",
"p1": "It will automatically add the lifetime pulls, 5★, and 4★ pity",
"p2": [
"When the",
"pity reaches 10, it will automatically be reset to 0"
],
"p3": [
"When the",
"pity reaches 90, it will automatically be reset to 0"
],
"p2": ["When the", "pity reaches 10, it will automatically be reset to 0"],
"p3": ["When the", "pity reaches 90, it will automatically be reset to 0"],
"p4": [
"After a 10x Wish, press",
"but keep in mind that the pity counter might not be accurate, because there is no way to tell when the drop occured (maybe you got it on the 1st or even the 10th pull). To ensure that the counter is still accurate, you need to check the history table and add it one-by-one like you do 1x Wishes."
],
"p5": [
"You can also press the",
"button to edit the values manually!"
],
"p5": ["You can also press the", "button to edit the values manually!"],
"p6": "Press the arrow on the bottom to see your pulls' details. A popup will show up when you get a 5★ or 4★. You can also add or edit the table manually."
}
},
@ -435,7 +415,8 @@
"beginners": "Beginners' Wish",
"standard": "Standard",
"character-event": "Character Event",
"weapon-event": "Weapon Event"
"weapon-event": "Weapon Event",
"chronicled": "Chronicled Wish"
},
"detail": {
"weapon": "Weapon",
@ -567,11 +548,7 @@
"calculateTalent": "Calculate Talent Material?",
"inputTalentLevel": "Input the 1st, 2nd & 3rd current talent level",
"inputTalentNotice": "If it has a different color, subtract it by 3",
"inputTalent": [
"1st talent lvl",
"2nd talent lvl",
"3rd talent lvl"
],
"inputTalent": ["1st talent lvl", "2nd talent lvl", "3rd talent lvl"],
"talentToLevel": "to level",
"calculate": "Calculate",
"unknownInformation": "There are some unknown information",
@ -580,11 +557,7 @@
"expWasted": "EXP Wasted",
"addToTodo": "Add to Todo List",
"addedToTodo": "Added to Todo List",
"talent": [
"Attack",
"Skill",
"Burst"
]
"talent": ["Attack", "Skill", "Burst"]
},
"expTable": {
"level": "Level",
@ -676,10 +649,7 @@
"todo": {
"title": "Todo List",
"summary": "Summary",
"empty": [
"Nothing to do yet 😀",
"Add some from the Items page or the Calculator!"
],
"empty": ["Nothing to do yet 😀", "Add some from the Items page or the Calculator!"],
"farmableToday": "Farmable Today",
"resin": "Resin needed",
"based": "Based on AR:{ar} and WL:{wl}",
@ -1053,4 +1023,4 @@
"characterCard": "Character Card",
"actionCard": "Action Card"
}
}
}

View File

@ -375,14 +375,14 @@
</svelte:head>
<div class="lg:ml-64 pt-20 px-4 md:px-8 lg:pt-8 max-w-screen-xl">
<div class="bg-item rounded-xl mb-4 p-4">
<!-- <div class="bg-item rounded-xl mb-4 p-4">
<p class="text-white inline-block mr-4">{$t('settings.version')} <b>3.3</b></p>
<a href="/changelog">
<Button>
{$t('settings.changelog')}
</Button>
</a>
</div>
</div> -->
<div class="bg-item rounded-xl mb-4 p-4 flex flex-col">
<p class="text-white">{$t('settings.multiple')}</p>
<div class="flex flex-col md:flex-row mt-2">
@ -450,8 +450,8 @@
{isSynced
? $t('settings.synced')
: $localModified && $synced
? $t('settings.waiting')
: $t('settings.syncing')}
? $t('settings.waiting')
: $t('settings.syncing')}
{#if isSynced}
<Icon path={mdiCheckCircleOutline} className="text-green-400" />
{:else if $localModified && !$synced}

View File

@ -39,6 +39,7 @@
'weapon-event': 'weapons',
standard: 'standard',
beginners: 'beginners',
chronicled: 'chronicled',
};
let errorProcessingPull = null;
@ -193,8 +194,8 @@
pull.type === 'character'
? characters[pull.id]
: pull.type === 'weapon'
? weaponList[pull.id]
: { name: 'Unknown', rarity: 3 };
? weaponList[pull.id]
: { name: 'Unknown', rarity: 3 };
selectedBanners[currentBannerIndex].total++;
@ -638,8 +639,8 @@
src={pull.type === 'character'
? `/images/characters/${pull.id}.png`
: pull.type === 'weapon'
? `/images/weapons/${pull.id}.png`
: '/images/wish.png'}
? `/images/weapons/${pull.id}.png`
: '/images/wish.png'}
alt={pull.name}
loading="lazy"
/>

View File

@ -296,10 +296,7 @@
$: hidden = id === 'beginners' && total === 0 && !manualInput;
</script>
<div
class="bg-item rounded-xl p-4 inline-flex flex-col w-full {id === 'beginners' ? 'mb-4' : ''} {hidden ? 'hidden' : ''}"
style="height: min-content;"
>
<div class="bg-item rounded-xl p-4 inline-flex flex-col w-full {hidden ? 'hidden' : ''}" style="height: min-content;">
<div class="flex mb-2">
<h2 class="font-display font-bold text-2xl text-white flex-1">{name}</h2>
{#if manualInput}
@ -459,8 +456,8 @@
characters[pull.id].rarity === 5
? 'text-legendary-from'
: characters[pull.id].rarity === 4
? 'text-rare-from'
: 'text-primary'
? 'text-rare-from'
: 'text-primary'
}`}>{$t(characters[pull.id].name)}</td
>
{:else if pull.type === 'weapon'}
@ -469,8 +466,8 @@
weaponList[pull.id].rarity === 5
? 'text-legendary-from'
: weaponList[pull.id].rarity === 4
? 'text-rare-from'
: 'text-primary'
? 'text-rare-from'
: 'text-primary'
}`}>{$t(weaponList[pull.id].name)}</td
>
{:else if pull.type === 'unknown_3_star'}

View File

@ -83,6 +83,6 @@
$: data, createGraph();
</script>
<div class="flex flex-col bg-item rounded-xl p-4 w-full" style="height: 200px;">
<div class="flex flex-col bg-item rounded-xl p-4 w-full">
<canvas width="500" height="200" bind:this={chart} />
</div>

View File

@ -214,7 +214,7 @@
$: fixedPointWinRateOff = percentageWinRateOff < 0.1 ? 2 : percentageWinRateOff < 2 ? 1 : 0;
</script>
<div class="flex flex-col items-center bg-item rounded-xl p-4 w-full mt-4">
<div class="flex flex-col items-center bg-item rounded-xl p-4 w-full">
<div class="flex flex-col items-center pb-4">
<p class="text-lg text-white leading-none font-semibold">{$t('wish.rank.title')}</p>
<p class="text-sm text-gray-400 leading-none">{$t('wish.rank.based')}</p>
@ -246,8 +246,8 @@
{loading.total
? '...'
: percentage < 50
? percentage.toFixed(fixedPoint)
: (100 - percentage).toFixed(fixedPoint)}%
? percentage.toFixed(fixedPoint)
: (100 - percentage).toFixed(fixedPoint)}%
</span>
</div>
</div>
@ -283,8 +283,8 @@
{loading.winRateOff.legendary
? '...'
: percentageWinRateOff.legendary < 50
? percentageWinRateOff.legendary.toFixed(fixedPointWinRateOff)
: (100 - percentageWinRateOff.legendary).toFixed(fixedPointWinRateOff)}%
? percentageWinRateOff.legendary.toFixed(fixedPointWinRateOff)
: (100 - percentageWinRateOff.legendary).toFixed(fixedPointWinRateOff)}%
</span>
</div>
</div>
@ -318,8 +318,8 @@
{loading.legendary
? '...'
: percentageLuck.legendary < 50
? percentageLuck.legendary.toFixed(fixedPointLegendary)
: (100 - percentageLuck.legendary).toFixed(fixedPointLegendary)}%
? percentageLuck.legendary.toFixed(fixedPointLegendary)
: (100 - percentageLuck.legendary).toFixed(fixedPointLegendary)}%
</span>
</div>
</div>
@ -350,8 +350,8 @@
{loading.rare
? '...'
: percentageLuck.rare < 50
? percentageLuck.rare.toFixed(fixedPointRare)
: (100 - percentageLuck.rare).toFixed(fixedPointRare)}%
? percentageLuck.rare.toFixed(fixedPointRare)
: (100 - percentageLuck.rare).toFixed(fixedPointRare)}%
</span>
</div>
</div>

View File

@ -25,7 +25,7 @@
let loading = true;
let wishCount = 0;
let box = [0, 1, 2, 3];
let box = [0, 1, 2, 4, 3];
const avg = {};
const percentages = {};
@ -276,7 +276,7 @@
avg['standard'] !== undefined &&
avg['weapon-event'].legendary.total > avg['standard'].legendary.total
) {
box = [0, 2, 1, 3];
box = [0, 2, 1, 4, 3];
}
if (updateCollectedCharacters && totalWish > 0) {
@ -309,6 +309,10 @@
<SummaryItem avg={avg[types[box[3]].id]} type={types[box[3]]} />
<div class="h-4 md:h-0" />
{/if}
{#if avg[types[box[4]].id]}
<SummaryItem avg={avg[types[box[4]].id]} type={types[box[4]]} />
<div class="h-4 md:h-0" />
{/if}
<div class="flex flex-col summary-item">
<div class="bg-item rounded-xl p-4 flex items-center w-full text-white mb-4" style="height: min-content;">
{$t('wish.wishesWorth')} <img class="w-4 h-4 mx-2" src="/images/primogem.png" alt="primogem" />

View File

@ -92,6 +92,10 @@
name: 'Weapon Event',
id: 'weapon-event',
},
500: {
name: 'Chronicled Wish',
id: 'chronicled',
},
};
let powershellScript = `Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex "&{$((New-Object System.Net.WebClient).DownloadString('https://gist.github.com/MadeBaruna/1d75c1d37d19eca71591ec8a31178235/raw/getlink.ps1'))} global"`;

View File

@ -25,6 +25,7 @@
let counter2;
let counter3;
let counter4;
let counter5;
let rank;
let wishTotal = {
@ -129,6 +130,7 @@
counter2.readLocalData();
counter3.readLocalData();
counter4.readLocalData();
counter5.readLocalData();
}
</script>
@ -218,22 +220,31 @@
id="standard"
name={$t('wish.types.standard')}
/>
<div class="flex flex-col w-full">
<Counter
bind:this={counter4}
manualInput={settings.manualInput}
id="beginners"
name={$t('wish.types.beginners')}
/>
<Counter
on:counterread={(val) => setRankWishTotal('chronicled', val)}
bind:this={counter5}
manualInput={settings.manualInput}
id="chronicled"
name={$t('wish.types.chronicled')}
/>
<Counter
bind:this={counter4}
manualInput={settings.manualInput}
id="beginners"
name={$t('wish.types.beginners')}
/>
<MonthlyGraph bind:data={monthlyData} />
<!-- <div class="flex flex-col w-full">
{#if Object.keys(monthlyData).length > 0}
<MonthlyGraph bind:data={monthlyData} />
{:else}
<div class="-mb-4" />
<div class="-mb-4" />
{/if}
<Rank bind:this={rank} {wishTotal} {wishPercentage} />
<div class="mt-4 flex justify-center">
<Ad type="mobile" variant="mpu" id="1" />
</div>
</div> -->
<div>
<Rank bind:this={rank} {wishTotal} {wishPercentage} />
<Ad type="mobile" variant="mpu" id="1" />
</div>
<Summary bind:monthlyData on:summaryread={(val) => setRankWishPercentage(val)} />
</div>

View File

@ -28,12 +28,14 @@
{ label: 'Character Event', value: 'characters' },
{ label: 'Weapon Event', value: 'weapons' },
{ label: 'Standard', value: 'standard' },
{ label: 'Chronicled Wish', value: 'chronicled' },
];
const typeNumber = {
characters: 300000,
weapons: 400000,
standard: 200000,
chronicled: 500000,
};
const spliceCount = {
@ -252,14 +254,17 @@
const rareTotalPull = data.pityCount.rare;
loading = false;
if (data.pullByDay.length === 0) hidePullByDay = true;
await tick();
if (Object.keys(data).length > 0) {
consData = data.constellation;
showDataCons();
await showDataCons();
}
Chart.defaults.global.defaultFontColor = '#ffffff';
Chart.defaults.global.defaultFontFamily = 'Poppins';
if (!chart) return;
new Chart(chart, {
type: 'bar',
data: {
@ -327,46 +332,48 @@
},
});
new Chart(chartPullByDay, {
type: 'line',
data: {
labels: data.pullByDay.map((e) => dayjs(e.day).format('MM/DD')),
datasets: [
{
label: 'Pull By Day %',
data: data.pullByDay.map((e) => e.percentage * 100),
borderColor: '#4E7CFF',
backgroundColor: '#4E7CFF',
borderWidth: 3,
pointRadius: 2,
fill: false,
type: 'line',
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
title: (tooltipItem) => {
return dayjs(data.pullByDay[tooltipItem[0].index].day).format('dddd, MMM DD YYYY');
if (!hidePullByDay) {
new Chart(chartPullByDay, {
type: 'line',
data: {
labels: data.pullByDay.map((e) => dayjs(e.day).format('MM/DD')),
datasets: [
{
label: 'Pull By Day %',
data: data.pullByDay.map((e) => e.percentage * 100),
borderColor: '#4E7CFF',
backgroundColor: '#4E7CFF',
borderWidth: 3,
pointRadius: 2,
fill: false,
type: 'line',
},
label: (tooltipItem) => {
return `Pull by day: ${numberFormatSecondary.format(
data.pullByDay[tooltipItem.index].percentage * totalWish,
)} (${numberFormat.format(tooltipItem.value)}%)`;
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
tooltips: {
mode: 'index',
intersect: false,
callbacks: {
title: (tooltipItem) => {
return dayjs(data.pullByDay[tooltipItem[0].index].day).format('dddd, MMM DD YYYY');
},
label: (tooltipItem) => {
return `Pull by day: ${numberFormatSecondary.format(
data.pullByDay[tooltipItem.index].percentage * totalWish,
)} (${numberFormat.format(tooltipItem.value)}%)`;
},
},
},
},
},
});
});
}
new Chart(chart2, {
type: 'bar',
@ -400,8 +407,6 @@
},
},
});
if (data.pullByDay.length === 0) hidePullByDay = true;
} catch (err) {
console.error(err);
error = err;
@ -448,6 +453,7 @@
await tick();
if (constChart) constChart.destroy();
if (!chart3) return;
constChart = new Chart(chart3, {
type: 'bar',
data: {
@ -697,12 +703,12 @@
</div>
{/if}
<div class="bg-background rounded-xl p-4 relative mb-4" style="height: 200px; width: 100%;">
<canvas bind:this={chart} />
<canvas bind:this={chart} id="chart" />
</div>
{#if !loadingCons}
<div class="bg-background rounded-xl p-4 relative mb-4" style="width: 100%;">
<div style="height: 400px; width: 100%;">
<canvas bind:this={chart3} />
<canvas bind:this={chart3} id="chart3" />
</div>
<div>
<Button size="sm" on:click={() => showDataCons(5)}>5★</Button>

View File

@ -7,7 +7,7 @@ const IMAGE_CACHE = `cacheimg${IMAGE_CACHE_VER}`;
const IMAGE_URL = `${self.location.origin}/images/`;
const changelog = ['Add Chiori & weapons', 'Update banners', 'Update timelines', 'Update achievements'];
const changelog = ['Add chronicled wish banner', 'Add Chiori & weapons', 'Update timelines', 'Update achievements'];
const channel = new BroadcastChannel('paimonmoe-sw');