feat: add era-based camp soundscapes

This commit is contained in:
2026-07-13 05:18:32 +09:00
parent 1eedd63163
commit b88a2d6ec2
21 changed files with 1347 additions and 14 deletions

View File

@@ -0,0 +1,119 @@
import type { AmbienceTrackKey, MusicTrackKey } from '../audio/audioAssets';
import type { CampSkinId } from './campSkins';
export type CampMusicGroupId = 'rally' | 'wayfarer' | 'grand-strategy' | 'frontier';
export type CampAmbienceId = 'campfire' | 'river-night' | 'mountain-wind' | 'nanzhong-night';
export type CampMusicTrackKey = Extract<
MusicTrackKey,
'camp-rally' | 'camp-wayfarer' | 'camp-grand-strategy' | 'camp-frontier'
>;
export type CampAmbienceTrackKey = Extract<
AmbienceTrackKey,
'campfire-ambience' | 'river-night-ambience' | 'mountain-wind-ambience' | 'nanzhong-night-ambience'
>;
export type CampMusicGroupDefinition = {
id: CampMusicGroupId;
trackKey: CampMusicTrackKey;
label: string;
volume: number;
};
export type CampAmbienceDefinition = {
id: CampAmbienceId;
trackKey: CampAmbienceTrackKey;
label: string;
volume: number;
};
export type CampSoundscapeMapping = {
musicGroupId: CampMusicGroupId;
ambienceId: CampAmbienceId;
};
export type CampSoundscape = {
skinId: CampSkinId;
music: CampMusicGroupDefinition;
ambience: CampAmbienceDefinition;
};
export const campMusicGroups: Record<CampMusicGroupId, CampMusicGroupDefinition> = {
rally: {
id: 'rally',
trackKey: 'camp-rally',
label: '결의와 출정',
volume: 0.22
},
wayfarer: {
id: 'wayfarer',
trackKey: 'camp-wayfarer',
label: '유랑의 밤',
volume: 0.18
},
'grand-strategy': {
id: 'grand-strategy',
trackKey: 'camp-grand-strategy',
label: '대업의 계책',
volume: 0.2
},
frontier: {
id: 'frontier',
trackKey: 'camp-frontier',
label: '변경과 북벌',
volume: 0.2
}
};
export const campAmbienceDefinitions: Record<CampAmbienceId, CampAmbienceDefinition> = {
campfire: {
id: 'campfire',
trackKey: 'campfire-ambience',
label: '장작불',
volume: 0.12
},
'river-night': {
id: 'river-night',
trackKey: 'river-night-ambience',
label: '밤의 강물',
volume: 0.1
},
'mountain-wind': {
id: 'mountain-wind',
trackKey: 'mountain-wind-ambience',
label: '산바람',
volume: 0.09
},
'nanzhong-night': {
id: 'nanzhong-night',
trackKey: 'nanzhong-night-ambience',
label: '남중의 밤',
volume: 0.11
}
};
export const campSoundscapeMapping: Record<CampSkinId, CampSoundscapeMapping> = {
'yellow-turban': { musicGroupId: 'rally', ambienceId: 'campfire' },
'anti-dong': { musicGroupId: 'rally', ambienceId: 'campfire' },
xuzhou: { musicGroupId: 'wayfarer', ambienceId: 'campfire' },
wandering: { musicGroupId: 'wayfarer', ambienceId: 'campfire' },
wolong: { musicGroupId: 'wayfarer', ambienceId: 'mountain-wind' },
'red-cliffs': { musicGroupId: 'grand-strategy', ambienceId: 'river-night' },
'jing-yi': { musicGroupId: 'grand-strategy', ambienceId: 'river-night' },
'hanzhong-shuhan': { musicGroupId: 'grand-strategy', ambienceId: 'mountain-wind' },
'jingzhou-crisis': { musicGroupId: 'grand-strategy', ambienceId: 'river-night' },
'yiling-baidi': { musicGroupId: 'grand-strategy', ambienceId: 'river-night' },
nanzhong: { musicGroupId: 'frontier', ambienceId: 'nanzhong-night' },
northern: { musicGroupId: 'frontier', ambienceId: 'mountain-wind' }
};
export function getCampSoundscape(skinId: CampSkinId): CampSoundscape {
const mapping = campSoundscapeMapping[skinId];
return {
skinId,
music: campMusicGroups[mapping.musicGroupId],
ambience: campAmbienceDefinitions[mapping.ambienceId]
};
}