Aghhh variant, variation, whatever
This commit is contained in:
@@ -128,11 +128,11 @@ class Paths
|
||||
return scriptPath;
|
||||
}
|
||||
|
||||
static public function chart(song:String, ?difficulty:String):String
|
||||
static public function chart(song:String, ?difficulty:String, ?variant:String):String
|
||||
{
|
||||
difficulty = (difficulty != null ? difficulty : Flags.DEFAULT_DIFFICULTY);
|
||||
|
||||
return getPath('songs/$song/charts/$difficulty.json', null);
|
||||
return getPath('songs/$song/charts/${variant != null ? variant + "/" : ""}$difficulty.json', null);
|
||||
}
|
||||
|
||||
public static function character(character:String):String {
|
||||
|
||||
@@ -139,7 +139,8 @@ class Chart {
|
||||
}
|
||||
}
|
||||
|
||||
if (includeMetaVariations & data.variants.length > 0) for (variant in data.variants) {
|
||||
data.metas = [];
|
||||
if (includeMetaVariations && data.variants.length > 0) for (variant in data.variants) {
|
||||
if (!data.metas.exists(variant) && Assets.exists(Paths.file('songs/$songName/meta-$variant.json')))
|
||||
data.metas.set(variant, loadChartMeta(songName, variant, fromMods));
|
||||
}
|
||||
@@ -147,8 +148,10 @@ class Chart {
|
||||
return data;
|
||||
}
|
||||
|
||||
public static function parse(songName:String, ?variant:String):ChartData {
|
||||
var chartPath = Paths.chart(songName, variant);
|
||||
public static function parse(songName:String, ?difficulty:String, ?variant:String):ChartData {
|
||||
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
|
||||
|
||||
var chartPath = Paths.chart(songName, difficulty, variant);
|
||||
var base:ChartData = {
|
||||
strumLines: [],
|
||||
noteTypes: [],
|
||||
@@ -162,7 +165,7 @@ class Chart {
|
||||
fromMods: Paths.assetsTree.existsSpecific(chartPath, "TEXT", MODS)
|
||||
};
|
||||
|
||||
var valid:Bool = true, namePrint = (variant == null || variant == '') ? '$songName' : '$songName ($variant)';
|
||||
var valid:Bool = true, namePrint = '$songName $difficulty' + ((variant != null && variant != '') ? ' ($variant)' : '');
|
||||
if (!Assets.exists(chartPath)) {
|
||||
Logs.error('Chart for song $namePrint at "$chartPath" was not found.');
|
||||
valid = false;
|
||||
@@ -256,22 +259,33 @@ class Chart {
|
||||
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
|
||||
if (saveSettings == null) saveSettings = {};
|
||||
|
||||
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents);
|
||||
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents && saveSettings.seperateGlobalEvents != true);
|
||||
|
||||
#if sys
|
||||
var songPath = saveSettings.songFolder == null ? 'assets/songs/${chart.meta.name}' : saveSettings.songFolder;
|
||||
var prefix = 'assets/songs/', assetsRoot = Paths.getAssetsRoot() + '/';
|
||||
var songPath = saveSettings.songFolder == null ? '${chart.meta.name}' : saveSettings.songFolder, prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null;
|
||||
var metaPath = '$songPath/meta.json', temp:String;
|
||||
if ((temp = Paths.assetsTree.getPath(metaPath)) != null) metaPath = temp;
|
||||
if ((temp = Paths.assetsTree.getPath(prefix + metaPath)) != null) metaPath = temp;
|
||||
else metaPath = assetsRoot + metaPath;
|
||||
|
||||
var chartFolder = saveSettings.folder == null ? ((variant == null || variant == '') ? 'charts' : 'charts/$variant') : saveSettings.folder;
|
||||
var chartPath = '$songPath/$chartFolder/${difficulty.trim()}.json';
|
||||
if ((temp = Paths.assetsTree.getPath(chartPath)) != null) chartPath = temp;
|
||||
if ((temp = Paths.assetsTree.getPath(prefix + chartPath)) != null) chartPath = temp;
|
||||
else chartPath = assetsRoot + chartPath;
|
||||
|
||||
if (saveSettings.saveChart == null || saveSettings.saveChart == true)
|
||||
CoolUtil.safeSaveFile(chartPath, Json.stringify(filteredChart, null, saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null));
|
||||
CoolUtil.safeSaveFile(chartPath, Json.stringify(filteredChart, null, prettyPrint));
|
||||
|
||||
if (filteredChart.meta != null && (saveSettings.overrideExistingMeta || !FileSystem.exists(metaPath)))
|
||||
CoolUtil.safeSaveFile(metaPath, makeMetaSaveable(filteredChart.meta));
|
||||
if (saveSettings.overrideExistingMeta || !FileSystem.exists(metaPath))
|
||||
CoolUtil.safeSaveFile(metaPath, Json.stringify(filterMetaForSaving(chart.meta), null, prettyPrint));
|
||||
|
||||
if (saveSettings.seperateGlobalEvents == true) {
|
||||
var eventsPath = '$songPath/events.json';
|
||||
if ((temp = Paths.assetsTree.getPath(prefix + eventsPath)) != null) eventsPath = temp;
|
||||
else eventsPath = assetsRoot + eventsPath;
|
||||
|
||||
CoolUtil.safeSaveFile(eventsPath, Json.stringify({events: filterEventsForSaving(chart.events, false, true)}, null, prettyPrint));
|
||||
}
|
||||
#end
|
||||
|
||||
return filteredChart;
|
||||
@@ -304,10 +318,10 @@ class Chart {
|
||||
var data = [];
|
||||
if (!saveLocalEvents && !saveGlobalEvents) return data;
|
||||
|
||||
for (event in chart.events) if ((saveLocalEvents && event.global != true) || (saveGlobalEvents && event.global == true)) {
|
||||
for (event in events) if ((saveLocalEvents && event.global != true) || (saveGlobalEvents && event.global == true)) {
|
||||
var copy = Reflect.copy(event);
|
||||
if (saveLocalEvents ? event.global != true : event.global == true) Reflect.deleteField(copy, "global"); // should NOT delete the field when saving with the local events and the event should have been global - Nex
|
||||
data.events.push(copy);
|
||||
data.push(copy);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
@@ -9,6 +9,10 @@ final class FreeplaySongSelectEvent extends CancellableEvent {
|
||||
* Difficulty name
|
||||
*/
|
||||
public var difficulty:String;
|
||||
/**
|
||||
* Variation Name
|
||||
*/
|
||||
public var variant:String;
|
||||
/**
|
||||
* Whenever opponent mode is enabled or not.
|
||||
*/
|
||||
|
||||
@@ -43,8 +43,6 @@ class FunkinSaveMacro {
|
||||
* SAVE FUNCTION
|
||||
*/
|
||||
var saveFuncBlocks:Array<Expr> = [for(f in fieldNames) macro $i{saveFieldName}.data.$f = $i{f}];
|
||||
|
||||
saveFuncBlocks.push(macro $i{"__flush"}());
|
||||
saveFuncBlocks.push(macro $i{saveFieldName}.flush());
|
||||
|
||||
fields.push({
|
||||
@@ -60,6 +58,8 @@ class FunkinSaveMacro {
|
||||
access: [APublic, AStatic]
|
||||
});
|
||||
|
||||
var loadFuncBlocks:Array<Expr> = [for(f in fieldNames) macro if ($i{saveFieldName}.data.$f != null) $i{f} = $i{saveFieldName}.data.$f];
|
||||
|
||||
/**
|
||||
* LOAD FUNCTION
|
||||
*/
|
||||
@@ -70,10 +70,7 @@ class FunkinSaveMacro {
|
||||
args: [],
|
||||
expr: {
|
||||
pos: Context.currentPos(),
|
||||
expr: EBlock([for(f in fieldNames)
|
||||
macro if ($i{saveFieldName}.data.$f != null)
|
||||
$i{f} = $i{saveFieldName}.data.$f
|
||||
, macro $i{"__load"}()])
|
||||
expr: EBlock(loadFuncBlocks)
|
||||
}
|
||||
}),
|
||||
access: [APublic, AStatic]
|
||||
|
||||
@@ -28,6 +28,7 @@ import flixel.util.FlxColor;
|
||||
class Charter extends UIState {
|
||||
public static var __song:String;
|
||||
static var __diff:String;
|
||||
static var __variant:String;
|
||||
static var __reload:Bool;
|
||||
|
||||
var chart(get, never):ChartData;
|
||||
@@ -114,11 +115,12 @@ class Charter extends UIState {
|
||||
private var SONGPOSINFO_BPM = TU.getRaw("songPosInfo.bpm");
|
||||
private var SONGPOSINFO_TIMESIGNATURE = TU.getRaw("songPosInfo.timeSignature");
|
||||
|
||||
public function new(song:String, diff:String, reload:Bool = true) {
|
||||
public function new(song:String, diff:String, variant:String, reload:Bool = true) {
|
||||
super();
|
||||
if (song != null) {
|
||||
__song = song;
|
||||
__diff = diff;
|
||||
__variant = variant;
|
||||
__reload = reload;
|
||||
}
|
||||
}
|
||||
@@ -578,7 +580,7 @@ class Charter extends UIState {
|
||||
dataDisplay.screenCenter(Y);
|
||||
dataDisplay.cameras = [charterCamera]; dataDisplay.x = -dataDisplay.width; add(dataDisplay);*/
|
||||
|
||||
DiscordUtil.call("onEditorLoaded", ["Chart Editor", __song + " (" + __diff + ")"]);
|
||||
DiscordUtil.call("onEditorLoaded", ["Chart Editor", __song + " (" + __diff + ")" + (__variant != null && __variant != "" ? " (" + __variant + ")" : "")]);
|
||||
}
|
||||
|
||||
override function destroy() {
|
||||
@@ -595,7 +597,7 @@ class Charter extends UIState {
|
||||
public function loadSong() {
|
||||
if (__reload) {
|
||||
EventsData.reloadEvents();
|
||||
PlayState.loadSong(__song, __diff, false, false);
|
||||
PlayState.loadSong(__song, __diff, __variant, false, false);
|
||||
__resetStatics();
|
||||
}
|
||||
Conductor.setupSong(PlayState.SONG);
|
||||
@@ -788,12 +790,13 @@ class Charter extends UIState {
|
||||
autoSaveTimer = Options.charterAutoSaveTime;
|
||||
if (!autoSaveNotif.cancelled) {
|
||||
buildChart();
|
||||
var songPath:String = '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}';
|
||||
|
||||
if (Options.charterAutoSavesSeparateFolder)
|
||||
Chart.save(songPath, PlayState.SONG, __autoSaveLocation, {saveMetaInChart: true, saveLocalEvents: true, saveGlobalEvents: true, folder: "autosaves", prettyPrint: Options.editorCharterPrettyPrint});
|
||||
else // These two chart saves are particular, to avoid any kind of loss, stuff like meta, global and local events will be save all together - Nex
|
||||
Chart.save(songPath, PlayState.SONG, __diff.toLowerCase(), {saveMetaInChart: true, saveLocalEvents: true, saveGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __autoSaveLocation, {saveMetaInChart: true, saveLocalEvents: true, seperateGlobalEvents: true, folder: 'autosaves', prettyPrint: Options.editorCharterPrettyPrint});
|
||||
else
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: true, saveLocalEvents: true, seperateGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
undos.save();
|
||||
}
|
||||
autoSaveNotif.cancelled = false;
|
||||
@@ -1476,8 +1479,8 @@ class Charter extends UIState {
|
||||
|
||||
public static function saveChart(shouldBuild:Bool = true, withEvents:Bool = true) {
|
||||
#if sys
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
saveTo('${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}', !withEvents, shouldBuild);
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: false, saveLocalEvents: withEvents, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
if (undos != null) undos.save();
|
||||
#else
|
||||
saveChartAs(shouldBuild, withEvents);
|
||||
@@ -1493,13 +1496,9 @@ class Charter extends UIState {
|
||||
|
||||
public static function saveEvents(shouldBuild:Bool = true) {
|
||||
#if sys
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
var data = {events: Chart.filterChartForSaving(PlayState.SONG, false, false, true).events};
|
||||
|
||||
var path = '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}/events.json';
|
||||
if (data.events != null && data.events.length > 0) CoolUtil.safeSaveFile(path, Json.stringify(data, null, Options.editorCharterPrettyPrint ? Flags.JSON_PRETTY_PRINT : null));
|
||||
else if (FileSystem.exists(path)) FileSystem.deleteFile(path); // Instead of replacing with a useless empty file, deletes the file directly - Nex
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveChart: false, seperateGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
if (undos != null) undos.save();
|
||||
#else
|
||||
saveEventsAs(shouldBuild);
|
||||
#end
|
||||
@@ -1507,7 +1506,7 @@ class Charter extends UIState {
|
||||
|
||||
public static function saveEventsAs(shouldBuild:Bool = true) {
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
var data = {events: Chart.filterChartForSaving(PlayState.SONG, false, false, true).events};
|
||||
var data = {events: Chart.filterEventsForSaving(PlayState.SONG.events, false, true)};
|
||||
|
||||
saveAs(data, null, Options.editorCharterPrettyPrint ? Flags.JSON_PRETTY_PRINT : null, {
|
||||
defaultSaveFile: 'events.json'
|
||||
@@ -1516,12 +1515,8 @@ class Charter extends UIState {
|
||||
|
||||
public static function saveMeta(shouldBuild:Bool = true) {
|
||||
#if sys
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
CoolUtil.safeSaveFile(
|
||||
'${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}/meta.json',
|
||||
Json.stringify(PlayState.SONG.meta == null ? {} : Chart.filterChartForSaving(PlayState.SONG, true, false, false).meta, null, Flags.JSON_PRETTY_PRINT)
|
||||
);
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveChart: false, overrideExistingMeta: true, prettyPrint: true});
|
||||
#else
|
||||
saveMetaAs(shouldBuild);
|
||||
#end
|
||||
@@ -1545,9 +1540,7 @@ class Charter extends UIState {
|
||||
}, null, shouldBuild);
|
||||
}
|
||||
|
||||
public static function saveAs(data:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String, ?options:SaveSubstate.SaveSubstateData, ?saveOptions:Map<String, Bool>, shouldBuild:Bool = true) {
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
public static function saveAs(data:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String, ?options:SaveSubstate.SaveSubstateData, ?saveOptions:Map<String, Bool>, shouldBuild:Bool = true) { if (shouldBuild && instance != null) instance.buildChart();
|
||||
var cur = FlxG.state;
|
||||
while(true) {
|
||||
if (instance != null || cur.subState == null) return cur.openSubState(new SaveSubstate(Json.stringify(data, replacer, space), options, saveOptions));
|
||||
@@ -1558,7 +1551,7 @@ class Charter extends UIState {
|
||||
#if sys
|
||||
public static function saveTo(path:String, separateEvents:Bool = false, shouldBuild:Bool = true) {
|
||||
if (shouldBuild && instance != null) instance.buildChart();
|
||||
Chart.save(path, PlayState.SONG, __diff.toLowerCase(), {saveMetaInChart: false, saveLocalEvents: !separateEvents, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: false, saveLocalEvents: !separateEvents, songFolder: path, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
}
|
||||
#end
|
||||
#end
|
||||
@@ -1570,17 +1563,17 @@ class Charter extends UIState {
|
||||
else {undos = null; FlxG.switchState(new CharterSelection()); Charter.instance.__clearStatics();}
|
||||
}
|
||||
|
||||
function _file_save_all(_) saveEverything();
|
||||
function _file_save(_) saveChart();
|
||||
function _file_saveas(_) saveChartAs();
|
||||
function _file_events_save(_) saveEvents();
|
||||
function _file_events_saveas(_) saveEventsAs();
|
||||
function _file_save_no_events(_) saveChart(true, false);
|
||||
function _file_saveas_no_events(_) saveChartAs(true, false);
|
||||
function _file_meta_save(_) saveMeta();
|
||||
function _file_meta_saveas(_) saveMetaAs();
|
||||
function _file_saveas_fnflegacy(_) saveLegacyChartAs();
|
||||
function _file_saveas_psych(_) savePsychChartAs();
|
||||
function _file_save_all(_) {saveEverything(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_save(_) {saveChart(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas(_) {saveChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_events_save(_) {saveEvents(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_events_saveas(_) {saveEventsAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_save_no_events(_) {saveChart(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_no_events(_) {saveChartAs(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_meta_save(_) {saveMeta(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_meta_saveas(_) {saveMetaAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_fnflegacy(_) {saveLegacyChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_psych(_) {savePsychChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
|
||||
function _edit_copy(_, playSFX=true) {
|
||||
if (playSFX) FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_COPY_SOUND));
|
||||
|
||||
@@ -26,7 +26,7 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
|
||||
public var curSong:ChartMetaData;
|
||||
|
||||
inline public function makeChartOption(d:String, name:String):TextOption {
|
||||
return new TextOption(d, getID('acceptDifficulty'), () -> FlxG.switchState(new Charter(name, d)));
|
||||
return new TextOption(d, getID('acceptDifficulty'), () -> FlxG.switchState(new Charter(name, d, null)));
|
||||
}
|
||||
|
||||
public function makeSongOption(s:ChartMetaData):IconOption {
|
||||
|
||||
@@ -65,6 +65,10 @@ class PlayState extends MusicBeatState
|
||||
* The selected difficulty name.
|
||||
*/
|
||||
public static var difficulty:String = Flags.DEFAULT_DIFFICULTY;
|
||||
/**
|
||||
* The selected variation name. (It can be null)
|
||||
*/
|
||||
public static var variation:Null<String>;
|
||||
/**
|
||||
* Whenever the week is coming from the mods folder or not.
|
||||
*/
|
||||
@@ -657,7 +661,7 @@ class PlayState extends MusicBeatState
|
||||
persistentDraw = true;
|
||||
|
||||
if (SONG == null)
|
||||
SONG = Chart.parse('tutorial', 'normal');
|
||||
SONG = Chart.parse('tutorial', difficulty = 'normal', variation = null);
|
||||
|
||||
scrollSpeed = SONG.scrollSpeed;
|
||||
|
||||
@@ -1352,7 +1356,7 @@ class PlayState extends MusicBeatState
|
||||
updateRatingStuff();
|
||||
|
||||
if (canAccessDebugMenus && chartingMode && controls.DEV_ACCESS)
|
||||
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false));
|
||||
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, variation, false));
|
||||
|
||||
if (Options.camZoomOnBeat && camZooming) {
|
||||
var beat = Conductor.getBeats(camZoomingEvery, camZoomingInterval, camZoomingOffset);
|
||||
@@ -1697,7 +1701,7 @@ class PlayState extends MusicBeatState
|
||||
|
||||
if (validScore) {
|
||||
#if !switch
|
||||
FunkinSave.setSongHighscore(SONG.meta.name, difficulty, {
|
||||
FunkinSave.setSongHighscore(SONG.meta.name, difficulty, variation, {
|
||||
score: songScore,
|
||||
misses: misses,
|
||||
accuracy: accuracy,
|
||||
@@ -1748,16 +1752,16 @@ class PlayState extends MusicBeatState
|
||||
FlxG.save.flush();
|
||||
}
|
||||
else {
|
||||
Logs.infos('Loading next song (${storyPlaylist[0].toLowerCase()}/$difficulty)', "PlayState");
|
||||
Logs.infos('Loading next song (${storyPlaylist[0].toLowerCase()}/$difficulty/$variation)', "PlayState");
|
||||
|
||||
registerSmoothTransition();
|
||||
|
||||
__loadSong(storyPlaylist[0], difficulty);
|
||||
__loadSong(storyPlaylist[0], difficulty, variation);
|
||||
FlxG.switchState(new PlayState());
|
||||
}
|
||||
}
|
||||
else if (chartingMode)
|
||||
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, false));
|
||||
FlxG.switchState(new funkin.editors.charter.Charter(SONG.meta.name, difficulty, variation, false));
|
||||
else
|
||||
FlxG.switchState(new FreeplayState());
|
||||
}
|
||||
@@ -2128,7 +2132,7 @@ class PlayState extends MusicBeatState
|
||||
* @param weekData Week Data
|
||||
* @param difficulty Week Difficulty
|
||||
*/
|
||||
public static function loadWeek(weekData:WeekData, ?difficulty:String) {
|
||||
public static function loadWeek(weekData:WeekData, ?difficulty:String, ?variation:String) {
|
||||
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
|
||||
storyWeek = weekData;
|
||||
storyPlaylist = [for (e in weekData.songs) e.name];
|
||||
@@ -2139,7 +2143,7 @@ class PlayState extends MusicBeatState
|
||||
campaignAccuracyCount = 0;
|
||||
chartingMode = false;
|
||||
opponentMode = coopMode = false;
|
||||
__loadSong(storyPlaylist[0], difficulty);
|
||||
__loadSong(storyPlaylist[0], difficulty, variation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2149,13 +2153,13 @@ class PlayState extends MusicBeatState
|
||||
* @param opponentMode Whenever opponent mode is on
|
||||
* @param coopMode Whenever co-op mode is on.
|
||||
*/
|
||||
public static function loadSong(_name:String, ?_difficulty:String, _opponentMode:Bool = false, _coopMode:Bool = false) {
|
||||
public static function loadSong(_name:String, ?_difficulty:String, ?_variation:String, _opponentMode:Bool = false, _coopMode:Bool = false) {
|
||||
if (_difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
|
||||
isStoryMode = false;
|
||||
opponentMode = _opponentMode;
|
||||
chartingMode = false;
|
||||
coopMode = _coopMode;
|
||||
__loadSong(_name, _difficulty);
|
||||
__loadSong(_name, _difficulty, _variation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2163,12 +2167,13 @@ class PlayState extends MusicBeatState
|
||||
* @param name Song name
|
||||
* @param difficulty Song difficulty
|
||||
*/
|
||||
public static function __loadSong(_name:String, _difficulty:String) {
|
||||
public static function __loadSong(_name:String, _difficulty:String, _variation:String) {
|
||||
difficulty = _difficulty;
|
||||
variation = _variation;
|
||||
seenCutscene = false;
|
||||
deathCounter = 0;
|
||||
|
||||
SONG = Chart.parse(_name, _difficulty);
|
||||
SONG = Chart.parse(_name, _difficulty, _variation);
|
||||
fromMods = SONG.fromMods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,14 @@ class FreeplayState extends MusicBeatState
|
||||
public var curSong:Null<ChartMetaData>;
|
||||
|
||||
/**
|
||||
* Current song metadata difficulty
|
||||
* Current song difficulties
|
||||
*/
|
||||
public var curSongDifficulty:Null<String>;
|
||||
public var curDifficulties:Array<String>;
|
||||
|
||||
/**
|
||||
* songs[curSelected].metas.get(curDiffMetaIndices[curDifficulty])
|
||||
*/
|
||||
public var curDiffMetaKeys:Array<String> = [];
|
||||
|
||||
/**
|
||||
* Currently selected song
|
||||
@@ -117,10 +122,12 @@ class FreeplayState extends MusicBeatState
|
||||
curSelected = k;
|
||||
}
|
||||
}
|
||||
updateCurSongMeta();
|
||||
|
||||
updateCurDifficulties();
|
||||
updateCurSong();
|
||||
|
||||
if (curSong != null) {
|
||||
for(k=>diff in songs[curSelected].difficulties) {
|
||||
for(k=>diff in curDifficulties) {
|
||||
if (diff == Options.freeplayLastDifficulty) {
|
||||
curDifficulty = k;
|
||||
}
|
||||
@@ -257,7 +264,7 @@ class FreeplayState extends MusicBeatState
|
||||
var dontPlaySongThisFrame = false;
|
||||
autoplayElapsed += elapsed;
|
||||
if (!disableAutoPlay && !songInstPlaying && (autoplayElapsed > timeUntilAutoplay)) {
|
||||
if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curSongDifficulty, curSong.instSuffix))) {
|
||||
if (curPlayingInst != (curPlayingInst = Paths.inst(curSong.name, curDifficulties[curDifficulty], curSong.instSuffix))) {
|
||||
var streamed = false;
|
||||
if (Options.streamedMusic) {
|
||||
var sound = Assets.getMusic(curPlayingInst, true, false);
|
||||
@@ -330,9 +337,9 @@ class FreeplayState extends MusicBeatState
|
||||
public function select() {
|
||||
updateCoopModes();
|
||||
|
||||
if (songs[curSelected].difficulties.length <= 0) return;
|
||||
if (curDifficulties.length == 0) return;
|
||||
|
||||
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(curSong.name, curSongDifficulty, __opponentMode, __coopMode));
|
||||
var event = event("onSelect", EventManager.get(FreeplaySongSelectEvent).recycle(curSong.name, curDifficulties[curDifficulty], curSong.variant, __opponentMode, __coopMode));
|
||||
|
||||
if (event.cancelled) return;
|
||||
|
||||
@@ -341,16 +348,17 @@ class FreeplayState extends MusicBeatState
|
||||
#end
|
||||
|
||||
Options.freeplayLastSong = curSong.name;
|
||||
Options.freeplayLastDifficulty = curSongDifficulty;
|
||||
Options.freeplayLastDifficulty = curDifficulties[curDifficulty];
|
||||
Options.freeplayLastVariation = curSong.variant;
|
||||
|
||||
PlayState.loadSong(event.song, event.difficulty, event.opponentMode, event.coopMode);
|
||||
PlayState.loadSong(event.song, event.difficulty, event.variant, event.opponentMode, event.coopMode);
|
||||
FlxG.switchState(new PlayState());
|
||||
}
|
||||
|
||||
public function convertChart() {
|
||||
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);
|
||||
trace('Converting ${curSong.name} ${curDifficulties[curDifficulty]} ${curSong.variant} to Codename format...');
|
||||
var chart = Chart.parse(curSong.name, curDifficulties[curDifficulty], curSong.variant);
|
||||
Chart.save(chart, curDifficulties[curDifficulty], curSong.variant);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,39 +366,35 @@ class FreeplayState extends MusicBeatState
|
||||
* @param change How much to change.
|
||||
* @param force Force the change if `change` is equal to 0
|
||||
*/
|
||||
public function changeDiff(change:Int = 0, force:Bool = false)
|
||||
{
|
||||
public function changeDiff(change:Int = 0, force:Bool = false) {
|
||||
if (change == 0 && !force) return;
|
||||
|
||||
var song = songs[curSelected];
|
||||
var validDifficulties = song.difficulties.length > 0;
|
||||
var event = event("onChangeDiff", EventManager.get(MenuChangeEvent).recycle(curDifficulty, validDifficulties ? FlxMath.wrap(curDifficulty + change, 0, song.difficulties.length-1) : 0, change));
|
||||
var validDifficulties = curDifficulties.length > 0;
|
||||
var event = event("onChangeDiff", EventManager.get(MenuChangeEvent).recycle(curDifficulty, validDifficulties ? FlxMath.wrap(curDifficulty + change, 0, curDifficulties.length-1) : 0, change));
|
||||
|
||||
if (event.cancelled) {
|
||||
if (force) updateCurSongMeta();
|
||||
if (force) updateCurSong();
|
||||
return;
|
||||
}
|
||||
|
||||
var prevInstSuffix = curSong.instSuffix;
|
||||
var prevSong = curSong;
|
||||
curDifficulty = event.value;
|
||||
updateCurSongMeta();
|
||||
updateCurSong();
|
||||
updateScore();
|
||||
|
||||
#if PRELOAD_ALL
|
||||
if (curSong.instSuffix != prevInstSuffix) {
|
||||
if (curSong != prevSong) {
|
||||
autoplayElapsed = 0;
|
||||
songInstPlaying = false;
|
||||
}
|
||||
#end
|
||||
|
||||
if (song.difficulties.length > 1)
|
||||
diffText.text = '< ${song.difficulties[curDifficulty].toUpperCase()} >';
|
||||
else
|
||||
diffText.text = validDifficulties ? song.difficulties[curDifficulty].toUpperCase() : "-";
|
||||
var text = validDifficulties ? curDifficulties[curDifficulty].toUpperCase() + (curSong != songs[curSelected] ? ' (${curSong.variant.toUpperCase()})' : '') : '-';
|
||||
diffText.text = curDifficulties.length > 1 ? '< $text >' : text;
|
||||
}
|
||||
|
||||
function updateScore() {
|
||||
if (songs[curSelected].difficulties.length <= 0) {
|
||||
if (curDifficulties.length == 0) {
|
||||
intendedScore = 0;
|
||||
return;
|
||||
}
|
||||
@@ -398,7 +402,7 @@ class FreeplayState extends MusicBeatState
|
||||
var changes:Array<HighscoreChange> = [];
|
||||
if (__coopMode) changes.push(CCoopMode);
|
||||
if (__opponentMode) changes.push(COpponentMode);
|
||||
var saveData = FunkinSave.getSongHighscore(curSong.name, curSongDifficulty, changes);
|
||||
var saveData = FunkinSave.getSongHighscore(curSong.name, curDifficulties[curDifficulty], curSong.variant, changes);
|
||||
intendedScore = saveData.score;
|
||||
}
|
||||
|
||||
@@ -448,8 +452,7 @@ class FreeplayState extends MusicBeatState
|
||||
* @param change How much to change
|
||||
* @param force Force the change, even if `change` is equal to 0.
|
||||
*/
|
||||
public function changeSelection(change:Int = 0, force:Bool = false)
|
||||
{
|
||||
public function changeSelection(change:Int = 0, force:Bool = false) {
|
||||
if (change == 0 && !force) return;
|
||||
|
||||
var event = event("onChangeSelection", EventManager.get(MenuChangeEvent).recycle(curSelected, FlxMath.wrap(curSelected + change, 0, songs.length-1), change));
|
||||
@@ -458,6 +461,7 @@ class FreeplayState extends MusicBeatState
|
||||
curSelected = event.value;
|
||||
if (event.playMenuSFX) CoolUtil.playMenuSFX(SCROLL, 0.7);
|
||||
|
||||
updateCurDifficulties();
|
||||
changeDiff(0, true);
|
||||
|
||||
#if PRELOAD_ALL
|
||||
@@ -491,13 +495,20 @@ class FreeplayState extends MusicBeatState
|
||||
}
|
||||
}
|
||||
|
||||
function updateCurSongMeta() {
|
||||
var song = songs[curSelected];
|
||||
if (song == null) {
|
||||
curSong = null;
|
||||
curSongDifficulty = null;
|
||||
function updateCurDifficulties() {
|
||||
curDiffMetaKeys.resize(0);
|
||||
curDifficulties = songs[curSelected].difficulties.copy();
|
||||
for (i in 0...curDifficulties.length) curDiffMetaKeys.push(null);
|
||||
for (variant => meta in songs[curSelected].metas) {
|
||||
curDifficulties = curDifficulties.concat(meta.difficulties);
|
||||
for (i in 0...meta.difficulties.length) curDiffMetaKeys.push(variant);
|
||||
}
|
||||
else if ((curSong = song.metas.get(curSongDifficulty = song.difficulties[curDifficulty])) == null)
|
||||
}
|
||||
|
||||
function updateCurSong() {
|
||||
var song = songs[curSelected];
|
||||
if (song == null) curSong = null;
|
||||
else if ((curSong = song.metas.get(curDiffMetaKeys[curDifficulty])) == null)
|
||||
curSong = song;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class PauseSubState extends MusicBeatSubstate
|
||||
case "Change Options":
|
||||
FlxG.switchState(new OptionsMenu((_) -> FlxG.switchState(new PlayState())));
|
||||
case "Exit to charter":
|
||||
FlxG.switchState(new Charter(PlayState.SONG.meta.name, PlayState.difficulty, false));
|
||||
FlxG.switchState(new Charter(PlayState.SONG.meta.name, PlayState.difficulty, PlayState.variation, false));
|
||||
case "Exit to menu":
|
||||
if (PlayState.chartingMode && Charter.undos.unsaved)
|
||||
game.saveWarn(false);
|
||||
|
||||
@@ -73,6 +73,7 @@ class Options
|
||||
*/
|
||||
public static var freeplayLastSong:String = null;
|
||||
public static var freeplayLastDifficulty:String = "normal";
|
||||
public static var freeplayLastVariation:String = null;
|
||||
public static var contributors:Array<funkin.backend.system.github.GitHubContributor.CreditsGitHubContributor> = [];
|
||||
public static var mainDevs:Array<Int> = []; // IDs
|
||||
public static var lastUpdated:Null<Float>;
|
||||
|
||||
@@ -11,14 +11,14 @@ import haxe.Unserializer;
|
||||
* Just add your save variables the way you would do in the Options.hx file.
|
||||
* The macro will automatically generate the `flush` and `load` functions.
|
||||
*/
|
||||
@:build(funkin.backend.system.macros.FunkinSaveMacro.build("save", "flush", "load"))
|
||||
@:build(funkin.backend.system.macros.FunkinSaveMacro.build("save", "__flush", "__load"))
|
||||
class FunkinSave {
|
||||
@:doNotSave public static var highscores:Map<HighscoreEntry, SongScore> = [];
|
||||
|
||||
/**
|
||||
* ONLY OPEN IF YOU WANT TO EDIT FUNCTIONS RELATED TO SAVING, LOADING OR HIGHSCORES.
|
||||
*/
|
||||
#if REGION
|
||||
@:doNotSave public static var highscores:Map<HighscoreEntry, SongScore> = [];
|
||||
|
||||
@:dox(hide) @:doNotSave private static var __eventAdded = false;
|
||||
@:doNotSave public static var save:FlxSave;
|
||||
|
||||
@@ -45,7 +45,8 @@ class FunkinSave {
|
||||
}
|
||||
}
|
||||
|
||||
private static function __load() {
|
||||
public static function load() {
|
||||
__load();
|
||||
if (save.data.highscores != null) {
|
||||
var temp;
|
||||
for (entryData in Reflect.fields(save.data.highscores)) if ((temp = __getHighscoreEntry(entryData)) != null)
|
||||
@@ -53,7 +54,8 @@ class FunkinSave {
|
||||
}
|
||||
}
|
||||
|
||||
private static function __flush() {
|
||||
public static function flush() {
|
||||
__flush();
|
||||
if (save.data.highscores == null) save.data.highscores = {};
|
||||
for (entry => score in highscores) Reflect.setField(save.data.highscores, __formatHighscoreEntry(entry), score);
|
||||
}
|
||||
@@ -62,7 +64,7 @@ class FunkinSave {
|
||||
try {
|
||||
var d = Unserializer.run(data);
|
||||
if (d.song is String)
|
||||
return HSongEntry(d.song, d.diff, d.changes);
|
||||
return HSongEntry(d.song, d.diff, d.variation, d.changes);
|
||||
else if (d.week is String)
|
||||
return HWeekEntry(d.week, d.diff);
|
||||
}
|
||||
@@ -72,10 +74,10 @@ class FunkinSave {
|
||||
|
||||
static function __formatHighscoreEntry(entry:HighscoreEntry):String {
|
||||
switch (entry) {
|
||||
case HWeekEntry(weekName:String, difficulty:String):
|
||||
case HWeekEntry(weekName, difficulty):
|
||||
return Serializer.run({week: weekName, diff: difficulty});
|
||||
case HSongEntry(songName:String, difficulty:String, variation:Null<String>, changes:Array<HighscoreChange>):
|
||||
var d = {
|
||||
case HSongEntry(songName, difficulty, variation, changes):
|
||||
var d:Dynamic = {
|
||||
song: songName,
|
||||
diff: difficulty,
|
||||
changes: changes
|
||||
@@ -92,14 +94,14 @@ class FunkinSave {
|
||||
* @param diff Song difficulty
|
||||
* @param changes Changes made to that song in freeplay.
|
||||
*/
|
||||
public static inline function getSongHighscore(name:String, diff:String, ?changes:Array<HighscoreChange>) {
|
||||
public static inline function getSongHighscore(name:String, diff:String, ?variation:String, ?changes:Array<HighscoreChange>) {
|
||||
if (changes == null) changes = [];
|
||||
return safeGetHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), changes));
|
||||
return safeGetHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), variation, changes));
|
||||
}
|
||||
|
||||
public static inline function setSongHighscore(name:String, diff:String, highscore:SongScore, ?changes:Array<HighscoreChange>) {
|
||||
public static inline function setSongHighscore(name:String, diff:String, ?variation:String, highscore:SongScore, ?changes:Array<HighscoreChange>) {
|
||||
if (changes == null) changes = [];
|
||||
if (safeRegisterHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), changes), highscore)) {
|
||||
if (safeRegisterHighscore(HSongEntry(name.toLowerCase(), diff.toLowerCase(), variation, changes), highscore)) {
|
||||
flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user