feat: support every song difficulty including Easy and Normal
Publish GitHub Pages output / publish (push) Successful in 41s
Publish GitHub Pages output / publish (push) Successful in 41s
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
</a>
|
||||
<a class="feature-card" href="/rating">
|
||||
<span class="feature-number">03</span>
|
||||
<div><h3>리더 레이팅</h3><p>입력한 편성으로 레이팅을 높이기 좋은 가창곡의 Hard·Expert를 최대 20개 추천하고, 5개씩 비교합니다.</p></div>
|
||||
<div><h3>리더 레이팅</h3><p>입력한 편성으로 레이팅을 높이기 좋은 가창곡의 모든 난이도를 최대 20개 추천하고, 5개씩 비교합니다.</p></div>
|
||||
<span class="arrow" aria-hidden="true">→</span>
|
||||
</a>
|
||||
<a class="feature-card" href="/data/boards">
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
export let mode: 'analysis' | 'rating' = 'analysis';
|
||||
|
||||
type CardRow = (typeof cardSummary.cards)[number];
|
||||
type DifficultyKey = 'hard' | 'expert';
|
||||
import { difficulties, difficultyLabel, isDifficulty, type DifficultyKey } from '$lib/data/difficulty.ts';
|
||||
type CollectionState = Record<string, { owned?: boolean; awakening?: number }>;
|
||||
type MemberBoards = Record<string, string[]>;
|
||||
type BoardCards = Record<string, Record<string, string>>;
|
||||
@@ -333,7 +333,7 @@
|
||||
const state = JSON.parse(stored) as Partial<SavedAnalysisState>;
|
||||
if (!legacy && state.schemaVersion !== 2) return;
|
||||
if (typeof state.songId === 'string' && songs.some((song) => song.id === state.songId)) selectedSongId = state.songId;
|
||||
if (state.difficulty === 'hard' || state.difficulty === 'expert') difficulty = state.difficulty;
|
||||
if (isDifficulty(state.difficulty)) difficulty = state.difficulty;
|
||||
songScoreBonusOverride = normalizeSongScoreBonusOverride(state.songScoreBonusOverride);
|
||||
|
||||
if (Array.isArray(state.cardIds) && state.cardIds.length === 5) {
|
||||
@@ -901,7 +901,7 @@
|
||||
<header class="page-header">
|
||||
<div>
|
||||
<h1>{mode === 'rating' ? '리더 레이팅' : '배치 분석'}</h1>
|
||||
<p class="page-description">{mode === 'rating' ? '입력한 편성으로 리더 가창곡의 Hard·Expert를 예상 레이팅 순으로 최대 20개 추천합니다. 결과는 5개씩 확인할 수 있습니다.' : '특정 악곡과 카드 조합에서 최고 점수를 낼 수 있는 스페셜 발동 순서와 빈도 감소 조합을 찾습니다.'}</p>
|
||||
<p class="page-description">{mode === 'rating' ? '입력한 편성으로 리더 가창곡의 모든 난이도를 예상 레이팅 순으로 최대 20개 추천합니다. 결과는 5개씩 확인할 수 있습니다.' : '특정 악곡과 카드 조합에서 최고 점수를 낼 수 있는 스페셜 발동 순서와 빈도 감소 조합을 찾습니다.'}</p>
|
||||
{#if mode === 'analysis' && selectedChart && selectedChart.scoreCalibrationSource !== 'measured' && selectedChart.scoreCalibrationSource !== 'formula-v1'}
|
||||
<p class="calibration-warning" role="status"><strong>추정 점수 안내</strong> 이 악곡의 점수 계수는 실측값이 아니므로 실제 점수와 오차가 크게 발생할 수 있습니다.</p>
|
||||
{/if}
|
||||
@@ -919,8 +919,7 @@
|
||||
<div class="song-picker-field"><SongPicker {charts} {difficulty} bind:value={selectedSongId} on:change={() => result = null} /></div>
|
||||
<label>난이도
|
||||
<select bind:value={difficulty} on:change={() => result = null}>
|
||||
<option value="expert">Expert</option>
|
||||
<option value="hard">Hard</option>
|
||||
{#each difficulties as value}<option {value}>{difficultyLabel(value)}</option>{/each}
|
||||
</select>
|
||||
</label>
|
||||
<label>가창 보너스 덮어쓰기 (0~10%)
|
||||
@@ -1036,7 +1035,7 @@
|
||||
{#if mode === 'analysis' || result}
|
||||
<section class="panel result" aria-labelledby="result-title">
|
||||
<div class="section-title"><div><span>{mode === 'rating' ? '03' : '02'}</span><h2 id="result-title">분석 결과</h2></div></div>
|
||||
{#if mode === 'rating' && result}<p class="board-guide"><strong>{selectedChart?.title} · {difficulty === 'expert' ? 'Expert' : 'Hard'}</strong> · 종합력 {overallPower.toLocaleString('ko-KR')} · 가창 보너스 10%</p>{/if}
|
||||
{#if mode === 'rating' && result}<p class="board-guide"><strong>{selectedChart?.title} · {difficultyLabel(difficulty)}</strong> · 종합력 {overallPower.toLocaleString('ko-KR')} · 가창 보너스 10%</p>{/if}
|
||||
{#if result}
|
||||
<div class="order-sections">
|
||||
<section class="order-section">
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
export let eventMode = false;
|
||||
|
||||
type CardRow = (typeof cardSummary.cards)[number];
|
||||
type DifficultyKey = 'hard' | 'expert';
|
||||
import { difficulties, difficultyLabel, isDifficulty, type DifficultyKey } from '$lib/data/difficulty.ts';
|
||||
type CollectionState = Record<string, { owned?: boolean; awakening?: number }>;
|
||||
type MemberBoards = Record<string, string[]>;
|
||||
type BoardCards = Record<string, Record<string, string>>;
|
||||
@@ -370,7 +370,7 @@
|
||||
function applySavedState(state: Partial<SavedState>): void {
|
||||
if (state.schemaVersion !== 1) throw new Error('Unsupported preset');
|
||||
if (typeof state.songId === 'string' && songs.some((song) => song.id === state.songId)) selectedSongId = state.songId;
|
||||
if (state.difficulty === 'hard' || state.difficulty === 'expert') difficulty = state.difficulty;
|
||||
if (isDifficulty(state.difficulty)) difficulty = state.difficulty;
|
||||
fixedCardIds = Array.from({ length: 4 }, (_, index) => cardById.has(state.fixedCardIds?.[index] ?? '') ? state.fixedCardIds![index] : '');
|
||||
candidateAwakening = normalizeAwakening(state.awakening);
|
||||
candidateGenerationBonus = typeof state.candidateGenerationBonus === 'number' && Number.isFinite(state.candidateGenerationBonus)
|
||||
@@ -422,7 +422,7 @@
|
||||
return {
|
||||
schemaVersion: 2,
|
||||
songId: typeof state.songId === 'string' ? state.songId : '',
|
||||
difficulty: state.difficulty === 'hard' ? 'hard' : 'expert',
|
||||
difficulty: isDifficulty(state.difficulty) ? state.difficulty : 'expert',
|
||||
cardIds: cards.map((card) => card.id),
|
||||
awakenings: cards.map((_, index) => Number.isFinite(state.awakenings?.[index]) ? normalizeAwakening(state.awakenings?.[index]) : 0),
|
||||
fixedCooldownReductions: cards.map((_, index) => normalizeFixedReduction(state.fixedCooldownReductions?.[index])),
|
||||
@@ -1140,7 +1140,7 @@
|
||||
<div><span>00</span><h2 id="baseline-title">기준 조합</h2></div>
|
||||
<strong>배치 분석 저장값</strong>
|
||||
</div>
|
||||
<p class="baseline-condition">{baselineChartMetadata?.title} · {baselineState.difficulty === 'expert' ? 'Expert' : 'Hard'}</p>
|
||||
<p class="baseline-condition">{baselineChartMetadata?.title} · {difficultyLabel(baselineState.difficulty)}</p>
|
||||
<div class="baseline-members">
|
||||
{#each baselineResult?.formationOrder ?? baselineState.cardIds as cardId, slot}
|
||||
<div><span>{slot + 1}</span><strong>{baselineCardLabel(cardId)}</strong></div>
|
||||
@@ -1164,7 +1164,7 @@
|
||||
<div class="section-title"><div><span>01</span><h2 id="conditions-title">탐색 조건</h2></div><strong>{ownedCardsOnly ? (eventMode ? '보유 이벤트 후보 대상' : '보유 5성 대상') : (eventMode ? '5성 + 대상 멤버 전 레어리티' : '5성 전체 대상')}</strong></div>
|
||||
<div class="song-fields">
|
||||
<div class="song-picker-field"><SongPicker {charts} {difficulty} bind:value={selectedSongId} on:change={() => result = null} /></div>
|
||||
<label>난이도<select bind:value={difficulty} on:change={() => result = null}><option value="expert">Expert</option><option value="hard">Hard</option></select></label>
|
||||
<label>난이도<select bind:value={difficulty} on:change={() => result = null}>{#each difficulties as value}<option {value}>{difficultyLabel(value)}</option>{/each}</select></label>
|
||||
<div class="chart-meta"><span>길이 {selectedChart?.durationSeconds ?? 0}초</span><span>노트 {selectedChart?.totalNotes?.toLocaleString('ko-KR') ?? 0}개</span><span>점수 계수 · {scoreCalibrationLabel}</span></div>
|
||||
</div>
|
||||
<div class="candidate-fields">
|
||||
|
||||
Reference in New Issue
Block a user