Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 61 additions & 52 deletions source/funkin/play/song/Song.hx
Original file line number Diff line number Diff line change
Expand Up @@ -846,92 +846,101 @@ class SongDifficulty
{
var suffix:String = (variation != null && variation != '' && variation != 'default') ? '-$variation' : '';

if (characters.playerVocals != null)
{
// The metadata explicitly defines the list of voices.
var playerIds:Array<String> = characters?.playerVocals ?? [characters.player];
var playerVoices:Array<String> = playerIds.map((id) -> Paths.voices(this.song.id, '-$id$suffix'));
var validVoices:Bool = true;

// Check if all voice paths exist before returning
// If not, fallback to the default method for resolving voices
for (voice in playerVoices)
{
if (voice == null || !Assets.exists(voice)) validVoices = false;
}
if (validVoices) return playerVoices;
}

// Automatically resolve voices by removing suffixes.
// For example, if `Voices-bf-car-erect.ogg` does not exist, check for `Voices-bf-erect.ogg`.
// Then, check for `Voices-bf-car.ogg`, then `Voices-bf.ogg`.
var playerId:String = characters.player;
var playerVoice:String = Paths.voices(this.song.id, '-${playerId}$suffix');

if (characters.playerVocals == null)
while (playerVoice != null && !Assets.exists(playerVoice))
{
var playerId:String = characters.player;
var playerVoice:String = Paths.voices(this.song.id, '-${playerId}$suffix');

// Remove the last suffix.
// For example, bf-car becomes bf.
playerId = playerId.split('-').slice(0, -1).join('-');
// Try again.
playerVoice = playerId == '' ? null : Paths.voices(this.song.id, '-${playerId}$suffix');
}
if (playerVoice == null)
{
// Try again without $suffix.
playerId = characters.player;
playerVoice = Paths.voices(this.song.id, '-${playerId}');
while (playerVoice != null && !Assets.exists(playerVoice))
{
// Remove the last suffix.
// For example, bf-car becomes bf.
playerId = playerId.split('-').slice(0, -1).join('-');
// Try again.
playerVoice = playerId == '' ? null : Paths.voices(this.song.id, '-${playerId}$suffix');
}
if (playerVoice == null)
{
// Try again without $suffix.
playerId = characters.player;
playerVoice = Paths.voices(this.song.id, '-${playerId}');
while (playerVoice != null && !Assets.exists(playerVoice))
{
// Remove the last suffix.
playerId = playerId.split('-').slice(0, -1).join('-');
// Try again.
playerVoice = playerId == '' ? null : Paths.voices(this.song.id, '-${playerId}$suffix');
}
}

return playerVoice != null ? [playerVoice] : [];
}
else
{
// The metadata explicitly defines the list of voices.
var playerIds:Array<String> = characters?.playerVocals ?? [characters.player];
var playerVoices:Array<String> = playerIds.map((id) -> Paths.voices(this.song.id, '-$id$suffix'));

return playerVoices;
}
return playerVoice != null ? [playerVoice] : [];
}

public function buildOpponentVoiceList():Array<String>
{
var suffix:String = (variation != null && variation != '' && variation != 'default') ? '-$variation' : '';

if (characters.opponentVocals != null)
{
// The metadata explicitly defines the list of voices.
var opponentIds:Array<String> = characters?.opponentVocals ?? [characters.opponent];
var opponentVoices:Array<String> = opponentIds.map((id) -> Paths.voices(this.song.id, '-$id$suffix'));
var validVoices:Bool = true;

// Check if all voice paths exist before returning
// If not, fallback to the default method for resolving voices
for (voice in opponentVoices)
{
if (voice == null || !Assets.exists(voice)) validVoices = false;
}
if (validVoices) return opponentVoices;
}

// Automatically resolve voices by removing suffixes.
// For example, if `Voices-bf-car-erect.ogg` does not exist, check for `Voices-bf-erect.ogg`.
// Then, check for `Voices-bf-car.ogg`, then `Voices-bf.ogg`.

if (characters.opponentVocals == null)
var opponentId:String = characters.opponent;
var opponentVoice:String = Paths.voices(this.song.id, '-${opponentId}$suffix');
while (opponentVoice != null && !Assets.exists(opponentVoice))
{
// Remove the last suffix.
opponentId = opponentId.split('-').slice(0, -1).join('-');
// Try again.
opponentVoice = opponentId == '' ? null : Paths.voices(this.song.id, '-${opponentId}$suffix');
}
if (opponentVoice == null)
{
var opponentId:String = characters.opponent;
var opponentVoice:String = Paths.voices(this.song.id, '-${opponentId}$suffix');
// Try again without $suffix.
opponentId = characters.opponent;
opponentVoice = Paths.voices(this.song.id, '-${opponentId}');
while (opponentVoice != null && !Assets.exists(opponentVoice))
{
// Remove the last suffix.
opponentId = opponentId.split('-').slice(0, -1).join('-');
// Try again.
opponentVoice = opponentId == '' ? null : Paths.voices(this.song.id, '-${opponentId}$suffix');
}
if (opponentVoice == null)
{
// Try again without $suffix.
opponentId = characters.opponent;
opponentVoice = Paths.voices(this.song.id, '-${opponentId}');
while (opponentVoice != null && !Assets.exists(opponentVoice))
{
// Remove the last suffix.
opponentId = opponentId.split('-').slice(0, -1).join('-');
// Try again.
opponentVoice = opponentId == '' ? null : Paths.voices(this.song.id, '-${opponentId}$suffix');
}
}

return opponentVoice != null ? [opponentVoice] : [];
}
else
{
// The metadata explicitly defines the list of voices.
var opponentIds:Array<String> = characters?.opponentVocals ?? [characters.opponent];
var opponentVoices:Array<String> = opponentIds.map((id) -> Paths.voices(this.song.id, '-$id$suffix'));

return opponentVoices;
}
return opponentVoice != null ? [opponentVoice] : [];
}

/**
Expand Down
Loading