feat: add roll quality

This commit is contained in:
2026-04-01 02:20:01 +07:00 Unverified
parent 8d3fd5ada0
commit bbf6aa3cb3
2 changed files with 48 additions and 10 deletions
+1
View File
@@ -141,6 +141,7 @@ export type EnkaLocs = {
export type Affix = { export type Affix = {
PropType: number; PropType: number;
Efficiency: number; Efficiency: number;
Position: number;
Value: number; Value: number;
}; };
+47 -10
View File
@@ -30,7 +30,7 @@ import { mockData } from "@/lib/mock";
import { buildDisplayRows } from "@/lib/rows"; import { buildDisplayRows } from "@/lib/rows";
import { buildRollSummary, RollSummary } from "@/lib/substat"; import { buildRollSummary, RollSummary } from "@/lib/substat";
import { Locale, SubstatOrder } from "@/type/enka"; import { Locale, SubstatOrder } from "@/type/enka";
import { PercentageFightProp } from "@/type/fightPropMap"; import { FightPropMapEnum, PercentageFightProp } from "@/type/fightPropMap";
import { ErrorPage } from "./error"; import { ErrorPage } from "./error";
import { ListPage } from "./list"; import { ListPage } from "./list";
@@ -216,6 +216,7 @@ export function card(app: App) {
error: errorType, error: errorType,
lang, lang,
substat: enableSubstat, substat: enableSubstat,
quality: enableRollQuality,
}, },
}) => { }) => {
log`Rendering ${uid}/${charId}`; log`Rendering ${uid}/${charId}`;
@@ -311,18 +312,30 @@ export function card(app: App) {
).map((t) => { ).map((t) => {
const a = char.equipList!.find((e) => e.flat.equipType === t); const a = char.equipList!.find((e) => e.flat.equipType === t);
if (!a) return null; if (!a) return null;
const appendPropIdList = a.reliquary?.appendPropIdList ?? [];
const props = enableRollQuality
? appendPropIdList.map((id) => ({
id: FightPropMapEnum[affixes[`${id}`].PropType],
...affixes[`${id}`],
}))
: [];
return { return {
set: a.flat.setId!, // it is an artifact, therefore this always exist set: a.flat.setId!, // it is an artifact, therefore this always exist
stars: a.flat.rankLevel, stars: a.flat.rankLevel,
level: a.reliquary!.level - 1, level: a.reliquary!.level - 1,
appendPropIdList: a.reliquary?.appendPropIdList ?? [], appendPropIdList,
icon: `/ui/${a.flat.icon}.png`, icon: `/ui/${a.flat.icon}.png`,
main: a.flat.reliquaryMainstat!, main: a.flat.reliquaryMainstat!,
sub: (a.flat.reliquarySubstats ?? []).sort( sub: (a.flat.reliquarySubstats ?? [])
(a, b) => .map((s) => ({
(SubstatOrder[a.appendPropId] ?? 999) - ...s,
(SubstatOrder[b.appendPropId] ?? 999), props: props.filter((p) => p.id === s.appendPropId),
), }))
.sort(
(a, b) =>
(SubstatOrder[a.appendPropId] ?? 999) -
(SubstatOrder[b.appendPropId] ?? 999),
),
}; };
}); });
const setCounts = artifacts.reduce<Record<number, number>>( const setCounts = artifacts.reduce<Record<number, number>>(
@@ -757,14 +770,14 @@ export function card(app: App) {
<div tw="absolute top-0 bottom-0 right-0 w-[23.1em] p-[.7em] flex flex-col justify-between"> <div tw="absolute top-0 bottom-0 right-0 w-[23.1em] p-[.7em] flex flex-col justify-between">
{artifacts.map((a) => {artifacts.map((a) =>
a ? ( a ? (
<div tw="h-[18%] bg-[#0000004f] rounded-[.3em] relative text-white overflow-hidden flex justify-between gap-[.75em]"> <div tw="h-[18%] bg-[#0000004f] rounded-[.3em] relative text-white overflow-hidden flex justify-between gap-[.5em]">
<img <img
src={a.icon} src={a.icon}
alt="artifact" alt="artifact"
tw="absolute top-1/2 -left-[8%] w-[45%] -translate-y-1/2 -translate-x-[10%] object-contain aspect-square scale-90" tw="absolute top-1/2 -left-[8%] w-[45%] -translate-y-1/2 -translate-x-[10%] object-contain aspect-square scale-90"
/> />
{/* main */} {/* main */}
<div tw="h-full w-[30%] text-right shrink-0 flex flex-col justify-center"> <div tw="h-full w-[30%] text-right shrink-0 flex flex-col justify-center mr-[.25em]">
<EnkaIcon <EnkaIcon
icon={a.main.mainPropId} icon={a.main.mainPropId}
tw="h-[1em] w-[1em] ml-auto max-h-[22%]" tw="h-[1em] w-[1em] ml-auto max-h-[22%]"
@@ -799,8 +812,28 @@ export function card(app: App) {
<div tw="flex flex-col flex-wrap mt-[.35em] mb-[.35em] mr-[.35em] w-full"> <div tw="flex flex-col flex-wrap mt-[.35em] mb-[.35em] mr-[.35em] w-full">
{a.sub.map((s, i) => ( {a.sub.map((s, i) => (
<div <div
tw={`flex items-center gap-[.25em] w-1/2 h-1/2 ${i === 3 ? "opacity-80" : ""}`} tw={`flex items-center pl-[.25em] relative gap-[.25em] w-1/2 h-1/2 ${i === 3 ? "opacity-80" : ""}`}
> >
{enableRollQuality && (
<div tw="absolute top-0 m-[.1em] left-[-.25em] bottom-0 right-[.25em] bg-gradient-to-t from-transparent to-black/25 rounded-[.2em] flex gap-0.5">
{s.props.map((p) => (
<div
tw="flex justify-center items-end grow"
style={{
borderBottomWidth: "1px",
borderStyle: "solid",
borderColor:
"rgba(255,255,255,.8)",
maxWidth: `${(p.Efficiency / s.props.length) * 100}%`,
}}
>
{Array(p.Position).fill(
<div tw="bg-[#fff8] w-1 h-1 mr-[3px] mb-[3px] rounded-full" />,
)}
</div>
))}
</div>
)}
<EnkaIcon <EnkaIcon
icon={s.appendPropId} icon={s.appendPropId}
tw="h-[1em] w-[1em]" tw="h-[1em] w-[1em]"
@@ -926,6 +959,10 @@ export function card(app: App) {
description: "Add substats breakdown bar under the card.", description: "Add substats breakdown bar under the card.",
default: false, default: false,
}), }),
quality: t.Boolean({
description: "Add roll quality under artifact substats.",
default: false,
}),
}, },
{ additionalProperties: true }, { additionalProperties: true },
), ),