Add weapons page

This commit is contained in:
Made Baruna 2021-06-07 13:27:32 +07:00
parent d160dfe229
commit ae8737aaab
No known key found for this signature in database
GPG key ID: 5AA5DA16AA5DCEAD
7 changed files with 299 additions and 171 deletions

View file

@ -108,7 +108,7 @@
{mobile}
{segment}
on:clicked={close}
active={['items', 'achievement', 'reminder', 'furnishing'].includes(segment)}
active={['items', 'achievement', 'reminder', 'furnishing', 'weapons'].includes(segment)}
image="/images/items.png"
label={$t('sidebar.database')}
items={[
@ -116,6 +116,7 @@
{ label: $t('sidebar.achievement'), href: '/achievement' },
{ label: $t('sidebar.reminder'), href: '/reminder' },
{ label: $t('sidebar.furnishing'), href: '/furnishing' },
{ label: $t('sidebar.weapons'), href: '/weapons' },
]}
/>
<SidebarItem

File diff suppressed because one or more lines are too long

View file

@ -11,6 +11,7 @@
"todoList": "Todo List",
"timeline": "Timeline",
"furnishing": "Furnishing",
"weapons": "Weapons",
"settings": "Settings",
"donate": "Donate"
},
@ -18,9 +19,7 @@
"welcome": "Welcome to Paimon.moe! 👋",
"message": "Your best Genshin Impact companion! Help you plan what to farm with ascension calculator, also track your progress with todo and wish counter.",
"banner": {
"featured": [
"Eula"
],
"featured": ["Eula"],
"summoned": "Summoned",
"percentage": "from all {rarity}",
"avg": "Pity average",
@ -121,10 +120,7 @@
"manualButton": "Enable Manual Input",
"errorBanner": "Banner time missmatch! Please adjust your server on settings page. Still not working? please leave a message on Discord 😅",
"globalWishTally": "Global Wish Tally",
"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",
@ -153,11 +149,7 @@
"server": "Select your server:",
"wishTallyCheck": "Submit pity for global wish tally",
"wishTally": "We are doing a global wish tally! You can submit your wish tally 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"],
"faqs": {
"title": "Import Wish History FAQ",
"q1": "How does it work?",
@ -279,11 +271,7 @@
"exportFinish": "Export success, please wait until the browser download the file!",
"wishTallyTitle": "Submit Wish Tally",
"wishTally": "We are doing a global wish tally! You can submit your wish tally 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 Tally",
"wishTallyThankyou": "Thankyou for participating!",
"manualTitle": "Manual Input Setting",
@ -295,22 +283,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",
"or",
@ -403,11 +382,7 @@
"calculateTalent": "Calculate Talent Material?",
"inputTalentLevel": "Input the 1st, 2nd & 3rd current talent level",
"inputTalentNotice": "If it has different color, substract 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",
@ -470,10 +445,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}",
@ -646,6 +618,17 @@
"em": "Elemental Mastery",
"er": "Energy Recharge",
"atkPercent": "ATK",
"physicalDamage": "Physical DMG Bonus"
"hpPercent": "HP",
"defPercent": "DEF",
"physicalDamage": "Physical DMG Bonus",
"bow": "Bow",
"polearm": "Polearm",
"sword": "Sword",
"catalyst": "Catalyst",
"claymore": "Claymore",
"ascensionMaterial": "Ascension Materials",
"asc": "ASC",
"lvl": "LVL",
"baseAtk": "Base ATK"
}
}
}

View file

@ -11,6 +11,7 @@
"todoList": "Todo List",
"timeline": "Timeline",
"furnishing": "Furnitur",
"weapons": "Senjata",
"settings": "Pengaturan",
"donate": "Donasi"
},
@ -91,10 +92,7 @@
"manualButton": "Nyalakan Input Manual",
"errorBanner": "Waktu banner salah! Coba sesuaikan server di halaman settings. Masih gak bisa? tolong chat di Discord 😅",
"globalWishTally": "Perhitungan Pity Wish Global",
"pityTooltip": [
"Ini adalah pity {rarity} sekarang",
"{count}x wish lagi untuk dijamin {rarity}"
],
"pityTooltip": ["Ini adalah pity {rarity} sekarang", "{count}x wish lagi untuk dijamin {rarity}"],
"import": {
"title": "Import Riwayat Wish",
"faqsButton": "FAQS - BACA DULU",
@ -123,11 +121,7 @@
"server": "Pilih server mu:",
"wishTallyCheck": "Submit pity untuk perhitungan pity global",
"wishTally": "Kita sedang melakukan perhitungan pity global! Kamu bisa mensubmit pity mu untuk berpartisipasi. Semua data pity akan dikumpulkan untuk mengetahui berapa pity rata-rata pengguna paimon.moe.",
"wishTallyCollected": [
"Yang dikumpulkan:",
"dan",
"pity dari riwayat wish mu"
],
"wishTallyCollected": ["Yang dikumpulkan:", "dan", "pity dari riwayat wish mu"],
"faqs": {
"title": "Import Riwayat Wish FAQS",
"q1": "Cara kerjanya gimana?",
@ -249,11 +243,7 @@
"exportFinish": "Export berhasil, harap tunggu sampai file nya sudah ter-download!",
"wishTallyTitle": "Submit Perhitungan Pity Wish",
"wishTally": "Kita sedang melakukan perhitungan pity global! Kamu bisa mensubmit pity mu untuk berpartisipasi. Semua data pity akan dikumpulkan untuk mengetahui berapa pity rata-rata pengguna paimon.moe.",
"wishTallyCollected": [
"Yang dikumpulkan:",
"dan",
"pity dari riwayat wish mu"
],
"wishTallyCollected": ["Yang dikumpulkan:", "dan", "pity dari riwayat wish mu"],
"wishTallySubmit": "Submit Perhitungan Pity Wish",
"wishTallyThankyou": "Terimakasih sudah berpartisipasi!",
"manualTitle": "Pengaturan Manual Input",
@ -265,22 +255,13 @@
"subtitle": "Setelah kamu melakukan x1 pull wish:",
"pressWhenYouGet": "Tekan {button} ketika kamu mendapatkan {rarity}★",
"p1": "Itu akan otomatis menambahkan total pull, 5★ dan, 4★ pity",
"p2": [
"Ketika",
"pity mencapai 10, angkanya akan otomatis reset menjadi 0"
],
"p3": [
"Ketika",
"pity mencapai 90, angkanya akan otomatis reset menjadi 0"
],
"p2": ["Ketika", "pity mencapai 10, angkanya akan otomatis reset menjadi 0"],
"p3": ["Ketika", "pity mencapai 90, angkanya akan otomatis reset menjadi 0"],
"p4": [
"Ketika kamu melakukan wish x10 pull, tekan",
"tapi counter pity nya tidak akan akurat, karena tidak tahu kapan drop nya terjadi (bisa saja kamu dapat nya saat pull ke 1 atau bisa saja ke 10). Untuk membuat counter nya akurat, kamu perlu mengecek nya di tabel riwayat wish mu dan tabahkan 1-per-1 seperti kamu melakukan 1x pull wish."
],
"p5": [
"Kamu juga bisa menekan",
"untuk mengedit nilai nya secara manual!"
],
"p5": ["Kamu juga bisa menekan", "untuk mengedit nilai nya secara manual!"],
"p6": [
"Tekan tombol panah dibawah untuk melihat detail riwayat mu. Sebuah form akan muncul ketika kamu mendapat",
"atau",
@ -371,11 +352,7 @@
"calculateTalent": "Hitung Material Talent?",
"inputTalentLevel": "Masukkan level talent ke 1, 2 dan 3 saat ini",
"inputTalentNotice": "Jika warna level nya berbeda, kurangi 3",
"inputTalent": [
"lvl talent ke 1",
"lvl talent ke 2",
"lvl talent ke 3"
],
"inputTalent": ["lvl talent ke 1", "lvl talent ke 2", "lvl talent ke 3"],
"talentToLevel": "ke level",
"calculate": "Hitung",
"unknownInformation": "Ada beberapa informasi yang tidak diketahui",
@ -438,10 +415,7 @@
"todo": {
"title": "Todo List",
"summary": "Summary",
"empty": [
"Belum ada yang ditambahkan 😀",
"Tambahkan todo dari halaman Items atau dari Kalkulator!"
],
"empty": ["Belum ada yang ditambahkan 😀", "Tambahkan todo dari halaman Items atau dari Kalkulator!"],
"farmableToday": "Bisa di farm hari ini",
"resin": "resin diperlukan",
"based": "Berdasarkan AR:{ar} and WL:{wl}",
@ -596,4 +570,4 @@
"(Beban maximum belum dikonfirmasi!)"
]
}
}
}

View file

@ -1,93 +0,0 @@
<script context="module">
import data from '../../data/weapons/en.json';
export async function preload() {
return { data };
}
</script>
<script>
import { t } from 'svelte-i18n';
import TableHeader from '../../components/Table/TableHeader.svelte';
export let data;
let weapons = [];
const rarity = {
2: 'text-green-400',
3: 'text-primary',
4: 'text-rare-from',
5: 'text-legendary-from',
};
function process() {
const _weapons = [];
for (const [id, weapon] of Object.entries(data)) {
_weapons.push({
id,
name: weapon.name,
type: weapon.type,
rarity: weapon.rarity,
atk: weapon.atk[weapon.atk.length - 1].toFixed(0),
secondary: weapon.secondary.name
? `${$t(`weapon.${weapon.secondary.name}`)} ${(
weapon.secondary.stats[weapon.secondary.stats.length - 1] * (weapon.secondary.name === 'em' ? 1 : 100)
).toFixed(0)}${weapon.secondary.name === 'em' ? '' : '%'}`
: '-',
});
}
weapons = _weapons;
}
process();
</script>
<svelte:head>
<title>Weapon List - Paimon.moe</title>
<meta name="description" content="Genshin Impact Weapon list and stats" />
<meta property="og:description" content="Genshin Impact Weapon list and stats" />
</svelte:head>
<div class="lg:ml-64 pt-20 lg:pt-8">
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('weapon.title')}</h1>
<p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;">
{$t('weapon.subtitle')}
</p>
<div class="block overflow-x-auto whitespace-no-wrap pb-8">
<div class="px-4 md:px-8 table max-w-full">
<table class="w-full block p-4 bg-item rounded-xl">
<thead>
<TableHeader />
<TableHeader>{$t('weapon.name')}</TableHeader>
<TableHeader>{$t('weapon.type')}</TableHeader>
<TableHeader>{$t('weapon.rarity')}</TableHeader>
<TableHeader>{$t('weapon.atk')}</TableHeader>
<TableHeader>{$t('weapon.secondary')}</TableHeader>
</thead>
<tbody class="text-white">
{#each weapons as weapon}
<tr class="cursor-pointer hover:bg-background">
<td class="border-gray-700 border-t py-1 text-center h-12">
<img src="/images/weapons/{weapon.id}.png" alt={weapon.type} class="h-full w-auto inline" />
</td>
<td class="border-gray-700 border-t py-1 pl-4 pr-2">
{weapon.name}
</td>
<td class="border-gray-700 border-t py-1 text-center h-8">
<img src="/images/weapons/{weapon.type}.png" alt={weapon.type} class="h-full w-auto inline" />
</td>
<td class="border-gray-700 border-t py-1 text-center text-2xl {rarity[weapon.rarity]}"></td>
<td class="border-gray-700 border-t py-1 px-1 text-center">
{weapon.atk}
</td>
<td class="border-gray-700 border-t py-1 pl-4">
{weapon.secondary}
</td>
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</div>

View file

@ -0,0 +1,111 @@
<script context="module">
import data from '../../data/weapons/en.json';
import { weaponList } from '../../data/weaponList.js';
export async function preload(page) {
const { id } = page.params;
const weapon = data[id];
const materials = weaponList[id].ascension[0].items;
return { id, weapon, materials };
}
</script>
<script>
import { mdiCircle, mdiStar } from '@mdi/js';
import { t } from 'svelte-i18n';
import Icon from '../../components/Icon.svelte';
const rarity = {
1: 'text-white',
2: 'text-green-400',
3: 'text-primary',
4: 'text-rare-from',
5: 'text-legendary-from',
};
/* prettier-ignore */
const showedIndex = [1, 6, 11, 16, 20, 21, 26, 31, 36, 41, 42, 47, 52, 53, 58, 63, 64, 69, 74, 75, 80, 85, 86, 91, 96];
const level = [1, 5, 10, 15, 20, 20, 25, 30, 35, 40, 40, 45, 50, 50, 55, 60, 60, 65, 70, 70, 75, 80, 80, 85, 90];
const ascen = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6];
const ascenSpan = [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3];
export let id;
export let weapon;
// export let materials;
$: multiplier = weapon.secondary.name === 'em' ? 1 : 100;
$: suffix = weapon.secondary.name === 'em' ? '' : '%';
</script>
<svelte:head>
<title>{weapon.name} - Paimon.moe</title>
</svelte:head>
<div class="lg:ml-64 pt-20 lg:pt-8 max-w-screen-xl md:pl-4">
<div class="flex flex-col-reverse xl:flex-row items-start">
<div class="px-4">
<h1 class="font-display font-black text-4xl md:text-5xl text-white">{weapon.name}</h1>
<div class="{rarity[weapon.rarity]} text-2xl flex items-center z-0 -mt-2 md:-mt-4">
{#each [...new Array(weapon.rarity)] as _}
<Icon path={mdiStar} />
{/each}
<Icon path={mdiCircle} size={0.4} className="mx-2 mt-1" color="white" />
<p class="text-base text-white font-semibold mt-1">{$t(`weapon.${weapon.type}`)}</p>
</div>
<p class="text-gray-200">{weapon.description}</p>
{#if weapon.skill.name}
<div class="p-4 rounded-xl bg-item flex flex-col mt-4">
<p class="font-black font-display text-xl text-white">{weapon.skill.name}</p>
<p class="skill-description text-white">{@html weapon.skill.description}</p>
</div>
{/if}
<div class="mt-4 block overflow-x-auto whitespace-no-wrap md:w-auto">
<div style="width: min-content;">
<div class="table max-w-full rounded-xl border border-gray-200 border-opacity-25">
<table class="text-gray-200 w-full">
<tr>
<td class="text-center whitespace-no-wrap border-gray-700 font-semibold px-2">
{$t('weapon.asc')}
</td>
<td class="text-center whitespace-no-wrap border-gray-700 font-semibold px-2">
{$t('weapon.lvl')}
</td>
<td class="text-center whitespace-no-wrap border-gray-700 font-semibold px-2">
{$t('weapon.baseAtk')}
</td>
{#if weapon.secondary.name}
<td class="text-center whitespace-no-wrap border-gray-700 font-semibold px-2">
{$t(`weapon.${weapon.secondary.name}`)}
</td>
{/if}
</tr>
{#each showedIndex as index, i}
<tr>
{#if [0, 5, 10, 13, 16, 19, 22].includes(i)}
<td rowspan={ascenSpan[i]} class="text-center border-t border-gray-700 px-2">{ascen[i]}</td>
{/if}
<td class="text-center border-t border-gray-700 px-2">{level[i]}</td>
<td class="text-center border-t border-gray-700 px-2">{Math.round(weapon.atk[index])}</td>
{#if weapon.secondary.stats}
<td class="text-center border-t border-gray-700 px-2">
{Math.round(weapon.secondary.stats[index] * multiplier)}{suffix}
</td>
{/if}
</tr>
{/each}
</table>
</div>
</div>
</div>
</div>
<img class="w-64 h-64 ml-4 max-w-full" src="/images/weapons/{id}.png" alt={weapon.name} />
</div>
</div>
<style>
td:not(:last-child) {
@apply border-r;
}
</style>

View file

@ -0,0 +1,152 @@
<script context="module">
import data from '../../data/weapons/en.json';
export async function preload() {
return { data };
}
</script>
<script>
import { t } from 'svelte-i18n';
import TableHeader from '../../components/Table/TableHeader.svelte';
export let data;
let weaponList = [];
let sortBy = 'name';
let sortOrder = true;
const rarity = {
2: 'text-green-400',
3: 'text-primary',
4: 'text-rare-from',
5: 'text-legendary-from',
};
function sort(by) {
if (sortBy === by) {
sortOrder = !sortOrder;
} else {
sortBy = by;
}
}
function process() {
const _weapons = [];
for (const [id, weapon] of Object.entries(data)) {
if (['amber_bead', 'ebony_bow', 'quartz', 'the_flagstaff'].includes(id)) continue;
_weapons.push({
id,
name: weapon.name,
type: weapon.type,
rarity: weapon.rarity,
atk: weapon.atk[weapon.atk.length - 1].toFixed(0),
secondary: weapon.secondary.name
? `${$t(`weapon.${weapon.secondary.name}`)} ${(
weapon.secondary.stats[weapon.secondary.stats.length - 1] * (weapon.secondary.name === 'em' ? 1 : 100)
).toFixed(0)}${weapon.secondary.name === 'em' ? '' : '%'}`
: '-',
});
}
weaponList = _weapons;
}
process();
$: weapons = weaponList.sort((a, b) => {
switch (sortBy) {
case 'name':
if (sortOrder) {
return a.name.localeCompare(b.name);
} else {
return b.name.localeCompare(a.name);
}
case 'type':
if (sortOrder) {
return a.type.localeCompare(b.type);
} else {
return b.type.localeCompare(a.type);
}
case 'rarity':
if (sortOrder) {
return a.rarity - b.rarity;
} else {
return b.rarity - a.rarity;
}
case 'atk':
if (sortOrder) {
return a.atk - b.atk;
} else {
return b.atk - a.atk;
}
case 'secondary':
if (sortOrder) {
return a.secondary.localeCompare(b.secondary);
} else {
return b.secondary.localeCompare(a.secondary);
}
}
});
</script>
<svelte:head>
<title>Weapon List - Paimon.moe</title>
<meta name="description" content="Genshin Impact Weapon list and stats" />
<meta property="og:description" content="Genshin Impact Weapon list and stats" />
</svelte:head>
<div class="lg:ml-64 pt-20 lg:pt-8">
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('weapon.title')}</h1>
<p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;">
{$t('weapon.subtitle')}
</p>
<div class="block overflow-x-auto whitespace-no-wrap pb-8">
<div class="px-4 md:px-8 table max-w-full">
<table class="w-full block p-4 bg-item rounded-xl">
<thead>
<TableHeader />
<TableHeader on:click={() => sort('name')} sort={sortBy === 'name'} order={sortOrder}>
{$t('weapon.name')}
</TableHeader>
<TableHeader on:click={() => sort('type')} sort={sortBy === 'type'} order={sortOrder}>
{$t('weapon.type')}
</TableHeader>
<TableHeader on:click={() => sort('rarity')} sort={sortBy === 'rarity'} order={sortOrder}>
{$t('weapon.rarity')}
</TableHeader>
<TableHeader on:click={() => sort('atk')} sort={sortBy === 'atk'} order={sortOrder}>
{$t('weapon.atk')}
</TableHeader>
<TableHeader on:click={() => sort('secondary')} sort={sortBy === 'secondary'} order={sortOrder}>
{$t('weapon.secondary')}
</TableHeader>
</thead>
<tbody class="text-white">
{#each weapons as weapon (weapon.id)}
<a href="/weapons/{weapon.id}" style="display: contents;">
<tr class="cursor-pointer hover:bg-background">
<td class="border-gray-700 border-t py-1 text-center h-12">
<img src="/images/weapons/{weapon.id}.png" alt={weapon.type} class="h-full w-auto inline" />
</td>
<td class="border-gray-700 border-t py-1 pl-4 pr-2">
{weapon.name}
</td>
<td class="border-gray-700 border-t py-1 text-center h-8">
<img src="/images/weapons/{weapon.type}.png" alt={weapon.type} class="h-full w-auto inline" />
</td>
<td class="border-gray-700 border-t py-1 text-center text-2xl {rarity[weapon.rarity]}"></td>
<td class="border-gray-700 border-t py-1 px-1 text-center">
{weapon.atk}
</td>
<td class="border-gray-700 border-t py-1 pl-4">
{weapon.secondary}
</td>
</tr>
</a>
{/each}
</tbody>
</table>
</div>
</div>
</div>