feat: show in-game note score with singer bonus
Publish GitHub Pages output / publish (push) Successful in 48s
Publish GitHub Pages output / publish (push) Successful in 48s
This commit is contained in:
+9
-1
@@ -1,5 +1,13 @@
|
|||||||
---
|
---
|
||||||
updatedAt: 2026-09-06T22:30:18+09:00
|
updatedAt: 2026-09-07T00:16:12+09:00
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026년 9월 7일
|
||||||
|
|
||||||
|
### 배치 분석의 인게임 1노트 점수 표시
|
||||||
|
|
||||||
|
`NEW` 배치 분석에서 기본 1노트 점수와 가창 보너스를 합산한 인게임 1노트 점수를 함께 확인할 수 있습니다. 일반 PERFECT·스킬/콤보 보너스 제외 기준이며, 가창 보너스 덮어쓰기 값도 즉시 반영합니다.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2026년 9월 6일
|
## 2026년 9월 6일
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
import PresetManager from '$lib/components/PresetManager.svelte';
|
import PresetManager from '$lib/components/PresetManager.svelte';
|
||||||
import ScoreTimelineChart from '$lib/components/ScoreTimelineChart.svelte';
|
import ScoreTimelineChart from '$lib/components/ScoreTimelineChart.svelte';
|
||||||
import SongPicker from '$lib/components/SongPicker.svelte';
|
import SongPicker from '$lib/components/SongPicker.svelte';
|
||||||
import { calculateBoardEffects, calculateExactScore, calculateUnitPower, countOptimizationCandidates, memoryParameterPermil, optimizeBoardConnectionCards, optimizeExactOrderAndCooldowns, perfectNoteScoreFromPower, toOptimizerCard } from '$lib/engine/index.ts';
|
import { calculateBoardEffects, calculateExactScore, calculateUnitPower, countOptimizationCandidates, finalNoteScore, memoryParameterPermil, optimizeBoardConnectionCards, optimizeExactOrderAndCooldowns, perfectNoteScoreFromPower, toOptimizerCard } from '$lib/engine/index.ts';
|
||||||
import type { CooldownReduction, EffectiveSkillWindow, ExactOptimizationResult, ExactSongChart, OptimizableConnectionCard, OptimizationProgress, ScoreAchievementProbabilities, SkillWindow } from '$lib/engine/index.ts';
|
import type { CooldownReduction, EffectiveSkillWindow, ExactOptimizationResult, ExactSongChart, OptimizableConnectionCard, OptimizationProgress, ScoreAchievementProbabilities, SkillWindow } from '$lib/engine/index.ts';
|
||||||
import { USER_DATA_STORAGE_KEY } from '$lib/storage/browser-storage';
|
import { USER_DATA_STORAGE_KEY } from '$lib/storage/browser-storage';
|
||||||
import { createScoreOptimizerWorker } from '$lib/workers/create-score-optimizer-worker.ts';
|
import { createScoreOptimizerWorker } from '$lib/workers/create-score-optimizer-worker.ts';
|
||||||
@@ -168,6 +168,7 @@
|
|||||||
})();
|
})();
|
||||||
$: overallPower = unitPower.overallPower;
|
$: overallPower = unitPower.overallPower;
|
||||||
$: perfectNoteScore = perfectNoteScoreFromPower(overallPower, selectedChart?.scoreRatio ?? null);
|
$: perfectNoteScore = perfectNoteScoreFromPower(overallPower, selectedChart?.scoreRatio ?? null);
|
||||||
|
$: inGamePerfectNoteScore = finalNoteScore(perfectNoteScore, boardEffects.directSongScoreBonusPercent);
|
||||||
$: scoreCalibrationLabel = selectedChart?.scoreCalibrationSource === 'formula-v1' ? '곡별 공식' : selectedChart?.scoreCalibrationSource === 'measured' ? '실측값' : '추정값';
|
$: scoreCalibrationLabel = selectedChart?.scoreCalibrationSource === 'formula-v1' ? '곡별 공식' : selectedChart?.scoreCalibrationSource === 'measured' ? '실측값' : '추정값';
|
||||||
$: timelineDuration = selectedChart?.durationSeconds ?? 0;
|
$: timelineDuration = selectedChart?.durationSeconds ?? 0;
|
||||||
$: displayedEffectiveActiveWindows = mergeEffectiveActiveWindows(result?.effectiveActiveWindows ?? []);
|
$: displayedEffectiveActiveWindows = mergeEffectiveActiveWindows(result?.effectiveActiveWindows ?? []);
|
||||||
@@ -883,7 +884,16 @@
|
|||||||
<input class="number-input" type="number" min="0" max="10" step="any" value={songScoreBonusOverride ?? ''} placeholder="실제 보드값" on:input={(event) => updateSongScoreBonusOverride(event.currentTarget)}>
|
<input class="number-input" type="number" min="0" max="10" step="any" value={songScoreBonusOverride ?? ''} placeholder="실제 보드값" on:input={(event) => updateSongScoreBonusOverride(event.currentTarget)}>
|
||||||
</label>
|
</label>
|
||||||
<div class="power-summary"><span>자동 계산 종합력</span><strong>{overallPower.toLocaleString('ko-KR')}</strong></div>
|
<div class="power-summary"><span>자동 계산 종합력</span><strong>{overallPower.toLocaleString('ko-KR')}</strong></div>
|
||||||
<div class="chart-meta"><span>길이 {selectedChart?.durationSeconds ?? 0}초</span><span>노트 {selectedChart?.totalNotes?.toLocaleString('ko-KR') ?? 0}개</span><span>1노트 {Math.ceil(perfectNoteScore).toLocaleString('ko-KR')}점 · {scoreCalibrationLabel}</span>{#if boardEffects.directSongScoreBonusPercent > 0 || songScoreBonusOverride !== null}<span>가창 보너스 {boardEffects.directSongScoreBonusPercent}%{songScoreBonusOverride === null ? '' : ' · 덮어쓰기'}</span>{/if}</div>
|
<div class="chart-meta">
|
||||||
|
<span>길이 {selectedChart?.durationSeconds ?? 0}초</span>
|
||||||
|
<span>노트 {selectedChart?.totalNotes?.toLocaleString('ko-KR') ?? 0}개</span>
|
||||||
|
<span>기본 1노트 {Math.ceil(perfectNoteScore).toLocaleString('ko-KR')}점 · {scoreCalibrationLabel}</span>
|
||||||
|
{#if boardEffects.directSongScoreBonusPercent > 0 || songScoreBonusOverride !== null}
|
||||||
|
<span>가창 보너스 {boardEffects.directSongScoreBonusPercent}%{songScoreBonusOverride === null ? '' : ' · 덮어쓰기'}</span>
|
||||||
|
{/if}
|
||||||
|
<span class="in-game-note-score">인게임 1노트 {inGamePerfectNoteScore.toLocaleString('ko-KR')}점</span>
|
||||||
|
</div>
|
||||||
|
<p class="note-score-guide">인게임 1노트는 일반 PERFECT 기준으로 가창 보너스를 반영한 점수입니다. 스킬·콤보 보너스는 제외하며, 기본점수의 소수점을 유지해 보너스를 적용한 뒤 올림합니다.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-fields">
|
<div class="card-fields">
|
||||||
@@ -1125,8 +1135,10 @@
|
|||||||
.power-summary { display: grid; gap: 4px; min-height: 42px; margin-top: 25px; padding: 7px 11px; border-radius: 9px; background: #22202a; }
|
.power-summary { display: grid; gap: 4px; min-height: 42px; margin-top: 25px; padding: 7px 11px; border-radius: 9px; background: #22202a; }
|
||||||
.power-summary span { color: #929cab; font-size: 12px; font-weight: 750; }
|
.power-summary span { color: #929cab; font-size: 12px; font-weight: 750; }
|
||||||
.power-summary strong { color: #f2a3c4; font-size: 16px; }
|
.power-summary strong { color: #f2a3c4; font-size: 16px; }
|
||||||
.chart-meta { display: flex; grid-column: 1 / -1; gap: 8px; height: 42px; align-items: center; }
|
.chart-meta { display: flex; flex-wrap: wrap; grid-column: 1 / -1; gap: 8px; min-height: 42px; align-items: center; }
|
||||||
.chart-meta span { padding: 7px 9px; border-radius: 7px; color: #adb5c2; background: #202631; font-size: 13px; white-space: nowrap; }
|
.chart-meta span { padding: 7px 9px; border-radius: 7px; color: #adb5c2; background: #202631; font-size: 13px; white-space: nowrap; }
|
||||||
|
.chart-meta .in-game-note-score { color: #f0f4ff; font-weight: 700; }
|
||||||
|
.note-score-guide { grid-column: 1 / -1; margin: 0; color: #adb5c2; font-size: 12px; line-height: 1.6; }
|
||||||
.card-fields { display: grid; gap: 9px; margin-top: 18px; }
|
.card-fields { display: grid; gap: 9px; margin-top: 18px; }
|
||||||
.card-field-header, .card-field { display: grid; grid-template-columns: minmax(280px, 1fr) clamp(120px, 10vw, 160px) clamp(280px, 24vw, 360px) clamp(180px, 16vw, 240px); gap: 9px; }
|
.card-field-header, .card-field { display: grid; grid-template-columns: minmax(280px, 1fr) clamp(120px, 10vw, 160px) clamp(280px, 24vw, 360px) clamp(180px, 16vw, 240px); gap: 9px; }
|
||||||
.card-field-header { padding: 0 2px; color: #8f98a8; font-size: 13px; font-weight: 800; }
|
.card-field-header { padding: 0 2px; color: #8f98a8; font-size: 13px; font-weight: 800; }
|
||||||
|
|||||||
Reference in New Issue
Block a user