fix: apply both solo bonuses to FUWAMOCO songs
Publish GitHub Pages output / publish (push) Successful in 49s

This commit is contained in:
2026-09-09 13:36:16 +09:00
parent 96bd5c4514
commit bb3573c4e7
3 changed files with 42 additions and 2 deletions
+4
View File
@@ -4,6 +4,10 @@ updatedAt: 2026-09-09T12:00:00+09:00
## 2026년 9월 9일
### FUWAMOCO 솔로 악곡 보너스 수정
`FIXED` 후와와와 모코코 둘만 가창하는 FUWAMOCO 악곡을 솔로 악곡으로 판정하여, 두 멤버의 솔로 악곡 보너스가 함께 적용되도록 수정했습니다.
### 연결 카드 최적화의 편성 대상 수정
`FIXED` 배치 분석의 연결 카드 최적화에서 편성에 없는 멤버의 파란 보드에도 카드를 필수 배치하던 문제를 수정했습니다. 큰 발동률 노드를 포함하는 필수 배치 조건은 편성 멤버에게만 적용하며, 편성 밖 보드의 전체 능력치·가창 보너스 등 점수에 기여하는 효과는 계속 반영합니다.
+32
View File
@@ -27,6 +27,38 @@ const cards = [
{ id: 'card-b', characterId: 'b', type: '퓨어', generation: '1기생' }
];
test('FUWAMOCO 악곡은 두 멤버의 솔로 보너스를 합산하고 단체 보너스를 제외한다', () => {
const sisters = ['chr-04016', 'chr-04017'];
const songSummary: BoardSummarySource = {
nodeGroups: Object.fromEntries(['solo', 'solo-fuwamoko', 'group'].map((mode) => [
`Y-${mode}`,
[{ characterIds: [], effect: {
id: `music_singer_type-${mode}`,
type: 'live_score_bonus_add_permil_up_by_music_skill_tree_character_and_music_singer_type',
value: 5
} }]
]))
};
const bonus = (singerCharacterIds: string[], singerType: string, mode: string, owners = sisters) =>
calculateBoardEffects(songSummary, Object.fromEntries(owners.map((id) => [id, [`Y-${mode}`]])),
[], '', { singerType, singerCharacterIds }).directSongScoreBonusPercent;
for (const singerType of ['solo', 'group']) {
for (const mode of ['solo', 'solo-fuwamoko']) {
assert.equal(bonus(sisters, singerType, mode), 1);
for (const sister of sisters) assert.equal(bonus(sisters, singerType, mode, [sister]), 0.5);
assert.equal(bonus([...sisters, 'other'], 'group', mode), 0);
assert.equal(bonus(sisters, singerType, mode, ['other']), 0);
}
assert.equal(bonus(sisters, singerType, 'group'), 0);
}
for (const sister of sisters) {
assert.equal(bonus([sister], 'solo', 'solo'), 0.5);
assert.equal(bonus([sister], 'solo', 'solo-fuwamoko'), 0);
}
assert.equal(bonus([...sisters, 'other'], 'group', 'group'), 1);
});
test('JP 3기생 보너스가 코보의 ID 3기생 보너스 상한을 소모하지 않는다', () => {
const summary: BoardSummarySource = {
nodeGroups: {
+6 -2
View File
@@ -75,10 +75,14 @@ function songBonusApplies(effect: BoardEffect, ownerId: string, song?: BoardEffe
if (!effect.id) return false;
const expectedType = effect.id.match(/music_singer_type-(all|group|solo)/)?.[1];
if (expectedType === 'all') return true;
if (!song || expectedType !== song.singerType) return false;
if (!song) return false;
const singers = song.singerCharacterIds ?? [];
// FUWAMOCO-only songs count as solo songs for both sisters.
const isFuwamoco = singers.length === 2 && singers.includes('chr-04016') && singers.includes('chr-04017');
const singerType = isFuwamoco ? 'solo' : song.singerType;
if (expectedType !== singerType) return false;
if (effect.id.endsWith('-fuwamoko')) {
return singers.length === 2 && singers.includes('chr-04016') && singers.includes('chr-04017');
return isFuwamoco && singers.includes(ownerId);
}
return singers.includes(ownerId);
}