instSuffix, meta.metas for freeplay preview

This commit is contained in:
Ralty
2025-08-08 00:07:49 +07:00
parent d3ef27b9c7
commit d2a113907a
6 changed files with 88 additions and 41 deletions
+6 -6
View File
@@ -88,18 +88,18 @@ class Paths
inline static public function music(key:String, ?library:String, ?ext:String)
return getPath('music/$key.${ext != null ? ext : Flags.SOUND_EXT}', library);
inline static public function voices(song:String, ?difficulty:String, ?prefix:String = "", ?ext:String) {
inline static public function voices(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Voices$prefix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Voices$prefix.${ext}', null);
var diff = getPath('songs/$song/song/Voices$suffix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Voices$suffix.${ext}', null);
}
inline static public function inst(song:String, ?difficulty:String, ?prefix:String = "", ?ext:String) {
inline static public function inst(song:String, ?difficulty:String, ?suffix:String = "", ?ext:String) {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
if (ext == null) ext = Flags.SOUND_EXT;
var diff = getPath('songs/$song/song/Inst$prefix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Inst$prefix.${ext}', null);
var diff = getPath('songs/$song/song/Inst$suffix-${difficulty}.${ext}', null);
return OpenFlAssets.exists(diff) ? diff : getPath('songs/$song/song/Inst$suffix.${ext}', null);
}
static public function image(key:String, ?library:String, checkForAtlas:Bool = false, ?ext:String) {
+26 -11
View File
@@ -83,13 +83,13 @@ class Chart {
return data;
}
public static function loadChartMeta(songName:String, ?difficulty:String, fromMods:Bool = true):ChartMetaData {
public static function loadChartMeta(songName:String, ?difficulty:String, fromMods:Bool = true, includeMetaDifficulties:Bool = false):ChartMetaData {
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
var metaPath = Paths.file('songs/${songName}/meta.json');
var metaDiffPath = Paths.file('songs/${songName}/meta-${difficulty}.json');
var data:ChartMetaData = null;
var data:ChartMetaData = null, fromDifficulty = false;
var fromMods:Bool = fromMods;
for (path in [metaDiffPath, metaPath]) if (Assets.exists(path)) {
fromMods = Paths.assetsTree.existsSpecific(path, "TEXT", MODS);
@@ -98,23 +98,31 @@ class Chart {
tempData.color = CoolUtil.getColorFromDynamic(tempData.color).getDefault(Flags.DEFAULT_COLOR);
data = tempData;
} catch(e) Logs.trace('Failed to load song metadata for ${songName} ($path): ${Std.string(e)}', ERROR);
if (data != null) break;
if (data != null) {
fromDifficulty = path == metaDiffPath;
break;
}
}
if (data == null) data = {
name: songName,
bpm: 100
};
if (data == null) {
data = {
name: songName,
bpm: Flags.DEFAULT_BPM
};
}
else {
data.name = songName;
data.setFieldDefault("bpm", Flags.DEFAULT_BPM);
}
data.name = songName;
data.setFieldDefault("bpm", Flags.DEFAULT_BPM);
data.setFieldDefault("displayName", data.name);
data.setFieldDefault("beatsPerMeasure", Flags.DEFAULT_BEATS_PER_MEASURE);
data.setFieldDefault("stepsPerBeat", Flags.DEFAULT_STEPS_PER_BEAT);
data.setFieldDefault("icon", Flags.DEFAULT_HEALTH_ICON);
data.setFieldDefault("difficulties", []);
data.setFieldDefault("coopAllowed", Flags.DEFAULT_COOP_ALLOWED);
data.setFieldDefault("opponentModeAllowed", Flags.DEFAULT_OPPONENT_MODE_ALLOWED);
data.setFieldDefault("displayName", data.name);
data.setFieldDefault("instSuffix", "");
if (data.difficulties.length <= 0) {
data.difficulties = [for(f in Paths.getFolderContent('songs/${songName}/charts/', false, fromMods ? MODS : SOURCE)) if (Path.extension(f.toUpperCase()) == "JSON") Path.withoutExtension(f)];
@@ -131,6 +139,12 @@ class Chart {
}
}
if (includeMetaDifficulties && !fromDifficulty) {
data.metas = [];
for (difficulty in data.difficulties) if (!data.metas.exists(difficulty) && Assets.exists(Paths.file('songs/${songName}/meta-${difficulty}.json')))
data.metas.set(difficulty, loadChartMeta(songName, difficulty, fromMods, false));
}
return data;
}
@@ -304,7 +318,8 @@ class Chart {
public static inline function makeMetaSaveable(meta:ChartMetaData, prettyPrint:Bool = true):String {
var data:Dynamic = Reflect.copy(meta);
if (data.color != null) data.color = new FlxColor(data.color).toWebString(); // dont even ask me - Nex
if (data.color != null) data.color = FlxColor.fromInt(data.color).toWebString(); // dont even ask me - Nex
Reflect.deleteField(data, 'metas');
return Json.stringify(data, null, prettyPrint ? Flags.JSON_PRETTY_PRINT : null);
}
}
+2
View File
@@ -28,6 +28,8 @@ typedef ChartMetaData = {
public var ?coopAllowed:Bool;
public var ?opponentModeAllowed:Bool;
public var ?customValues:Dynamic;
public var ?metas:Map<String, ChartMetaData>;
public var ?instSuffix:String;
}
typedef ChartStrumLine = {
+2 -2
View File
@@ -601,7 +601,7 @@ class Charter extends UIState {
Conductor.setupSong(PlayState.SONG);
noteTypes = PlayState.SONG.noteTypes;
FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff)));
FlxG.sound.setMusic(FlxG.sound.load(Paths.inst(__song, __diff, PlayState.SONG.meta.instSuffix)));
vocals = Assets.exists(Paths.voices(__song, __diff)) ? FlxG.sound.load(Paths.voices(__song, __diff)) : new FlxSound();
vocals.group = FlxG.sound.defaultMusicGroup;
@@ -680,7 +680,7 @@ class Charter extends UIState {
if (FlxG.sound.music.loaded)
wavesToGenerate.push({name: "Inst.ogg", sound: FlxG.sound.music});
if (PlayState.SONG.meta.needsVoices != false && vocals.loaded)
if (vocals.loaded)
wavesToGenerate.push({name: "Voices.ogg", sound: vocals});
for (strumLine in strumLines)
+1 -1
View File
@@ -1113,7 +1113,7 @@ class PlayState extends MusicBeatState
curSong = songData.meta.name.toLowerCase();
curSongID = curSong.replace(" ", "-");
FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty))));
FlxG.sound.setMusic(inst = FlxG.sound.load(Assets.getMusic(Paths.inst(SONG.meta.name, difficulty, SONG.meta.instSuffix))));
var vocalsPath = Paths.voices(SONG.meta.name, difficulty);
vocals = Assets.exists(vocalsPath) ? FlxG.sound.load(Options.streamedVocals ? Assets.getMusic(vocalsPath) : vocalsPath) : new FlxSound();
+51 -21
View File
@@ -19,6 +19,16 @@ class FreeplayState extends MusicBeatState
*/
public var songs:Array<ChartMetaData> = [];
/**
* Current song metadata
*/
public var curSong:Null<ChartMetaData>;
/**
* Current song metadata difficulty
*/
public var curSongDifficulty:Null<String>;
/**
* Currently selected song
*/
@@ -107,7 +117,9 @@ class FreeplayState extends MusicBeatState
curSelected = k;
}
}
if (songs[curSelected] != null) {
updateCurSongMeta();
if (curSong != null) {
for(k=>diff in songs[curSelected].difficulties) {
if (diff == Options.freeplayLastDifficulty) {
curDifficulty = k;
@@ -238,14 +250,14 @@ class FreeplayState extends MusicBeatState
scoreText.x = coopText.x = scoreBG.x + 4;
diffText.x = Std.int(scoreBG.x + ((scoreBG.width - diffText.width) / 2));
interpColor.fpsLerpTo(songs[curSelected].color, 0.0625);
interpColor.fpsLerpTo(curSong.color, 0.0625);
bg.color = interpColor.color;
#if PRELOAD_ALL
var dontPlaySongThisFrame = false;
autoplayElapsed += elapsed;
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay || FlxG.keys.justPressed.SPACE)) {
if (curPlayingInst != (curPlayingInst = Paths.inst(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty]))) {
if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curSongDifficulty, curSong.instSuffix))) {
var streamed = false;
if (Options.streamedMusic) {
var sound = Assets.getMusic(curPlayingInst, true, false);
@@ -253,7 +265,7 @@ class FreeplayState extends MusicBeatState
if (streamed && autoplayShouldPlay) {
FlxG.sound.playMusic(sound, 0);
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
Conductor.changeBPM(curSong.bpm, curSong.beatsPerMeasure, curSong.stepsPerBeat);
}
}
@@ -268,7 +280,7 @@ class FreeplayState extends MusicBeatState
if (sound != null && autoplayShouldPlay) {
FlxG.sound.playMusic(sound, 0);
Conductor.changeBPM(songs[curSelected].bpm, songs[curSelected].beatsPerMeasure, songs[curSelected].stepsPerBeat);
Conductor.changeBPM(curSong.bpm, curSong.beatsPerMeasure, curSong.stepsPerBeat);
}
}
if (!disableAsyncLoading) Main.execAsync(huh);
@@ -302,7 +314,6 @@ class FreeplayState extends MusicBeatState
function updateCoopModes() {
__opponentMode = false;
__coopMode = false;
var curSong = songs[curSelected];
if (curSong.coopAllowed && curSong.opponentModeAllowed) {
__opponentMode = curCoopMode % 2 == 1;
__coopMode = curCoopMode >= 2;
@@ -321,7 +332,7 @@ class FreeplayState extends MusicBeatState
if (songs[curSelected].difficulties.length <= 0) return;
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], __opponentMode, __coopMode));
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(curSong.name, curSongDifficulty, __opponentMode, __coopMode));
if (event.cancelled) return;
@@ -329,17 +340,17 @@ class FreeplayState extends MusicBeatState
autoplayShouldPlay = false;
#end
Options.freeplayLastSong = songs[curSelected].name;
Options.freeplayLastDifficulty = songs[curSelected].difficulties[curDifficulty];
Options.freeplayLastSong = curSong.name;
Options.freeplayLastDifficulty = curSongDifficulty;
PlayState.loadSong(event.song, event.difficulty, event.opponentMode, event.coopMode);
FlxG.switchState(new PlayState());
}
public function convertChart() {
trace('Converting ${songs[curSelected].name} (${songs[curSelected].difficulties[curDifficulty]}) to Codename format...');
var chart = Chart.parse(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty]);
Chart.save('${Main.pathBack}assets/songs/${songs[curSelected].name}', chart, songs[curSelected].difficulties[curDifficulty]);
trace('Converting ${curSong.name} (${curSongDifficulty}) to Codename format...');
var chart = Chart.parse(curSong.name, curSongDifficulty);
Chart.save('${Main.pathBack}assets/songs/${curSong.name}', chart, curSongDifficulty);
}
/**
@@ -355,10 +366,13 @@ class FreeplayState extends MusicBeatState
var validDifficulties = curSong.difficulties.length > 0;
var event = event("onChangeDiff", EventManager.get(MenuChangeEvent).recycle(curDifficulty, validDifficulties ? FlxMath.wrap(curDifficulty + change, 0, curSong.difficulties.length-1) : 0, change));
if (event.cancelled) return;
if (event.cancelled) {
updateCurSongMeta();
return;
}
curDifficulty = event.value;
updateCurSongMeta();
updateScore();
if (curSong.difficulties.length > 1)
@@ -376,7 +390,7 @@ class FreeplayState extends MusicBeatState
var changes:Array<HighscoreChange> = [];
if (__coopMode) changes.push(CCoopMode);
if (__opponentMode) changes.push(COpponentMode);
var saveData = FunkinSave.getSongHighscore(songs[curSelected].name, songs[curSelected].difficulties[curDifficulty], changes);
var saveData = FunkinSave.getSongHighscore(curSong.name, curSongDifficulty, changes);
intendedScore = saveData.score;
}
@@ -397,9 +411,9 @@ class FreeplayState extends MusicBeatState
*/
public function changeCoopMode(change:Int = 0, force:Bool = false) {
if (change == 0 && !force) return;
if (!songs[curSelected].coopAllowed && !songs[curSelected].opponentModeAllowed) return;
if (!curSong.coopAllowed && !curSong.opponentModeAllowed) return;
var bothEnabled = songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed;
var bothEnabled = curSong.coopAllowed && curSong.opponentModeAllowed;
var event = event("onChangeCoopMode", EventManager.get(MenuChangeEvent).recycle(curCoopMode, FlxMath.wrap(curCoopMode + change, 0, bothEnabled ? 3 : 1), change));
if (event.cancelled) return;
@@ -408,12 +422,19 @@ class FreeplayState extends MusicBeatState
updateScore();
#if PRELOAD_ALL
if (songs[curSelected] != curSong) {
autoplayElapsed = 0;
songInstPlaying = false;
}
#end
var key = "[TAB] "; // TODO: make this configurable
if (bothEnabled) {
coopText.text = key + coopLabels[curCoopMode];
} else {
coopText.text = key + coopLabels[curCoopMode * (songs[curSelected].coopAllowed ? 2 : 1)];
coopText.text = key + coopLabels[curCoopMode * (curSong.coopAllowed ? 2 : 1)];
}
}
@@ -426,7 +447,6 @@ class FreeplayState extends MusicBeatState
{
if (change == 0 && !force) return;
var bothEnabled = songs[curSelected].coopAllowed && songs[curSelected].opponentModeAllowed;
var event = event("onChangeSelection", EventManager.get(MenuChangeEvent).recycle(curSelected, FlxMath.wrap(curSelected + change, 0, songs.length-1), change));
if (event.cancelled) return;
@@ -440,7 +460,7 @@ class FreeplayState extends MusicBeatState
songInstPlaying = false;
#end
coopText.visible = songs[curSelected].coopAllowed || songs[curSelected].opponentModeAllowed;
coopText.visible = curSong.coopAllowed || curSong.opponentModeAllowed;
}
function updateOptionsAlpha() {
@@ -465,6 +485,16 @@ class FreeplayState extends MusicBeatState
item.alpha = selectedAlpha;
}
}
function updateCurSongMeta() {
var song = songs[curSelected];
if (song == null) {
curSong = null;
curSongDifficulty = null;
}
else if ((curSong = song.metas.get(curSongDifficulty = curSong.difficulties[curDifficulty])) == null)
curSong = song;
}
}
class FreeplaySonglist {
@@ -485,7 +515,7 @@ class FreeplaySonglist {
}
if (songsFound == null) songsFound = Paths.getFolderDirectories("songs", false, source);
if (songsFound.length > 0) {
for (s in songsFound) songs.push(Chart.loadChartMeta(s, Flags.DEFAULT_DIFFICULTY, source == MODS));
for (s in songsFound) songs.push(Chart.loadChartMeta(s, source == MODS));
return false;
}
return true;