Skip to content

Commit 9c7bb8f

Browse files
committed
Aghhh variant, variation, whatever
1 parent 6112e2f commit 9c7bb8f

File tree

11 files changed

+146
-119
lines changed

11 files changed

+146
-119
lines changed

source/funkin/backend/assets/Paths.hx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ class Paths
128128
return scriptPath;
129129
}
130130

131-
static public function chart(song:String, ?difficulty:String):String
131+
static public function chart(song:String, ?difficulty:String, ?variant:String):String
132132
{
133133
difficulty = (difficulty != null ? difficulty : Flags.DEFAULT_DIFFICULTY);
134134

135-
return getPath('songs/$song/charts/$difficulty.json', null);
135+
return getPath('songs/$song/charts/${variant != null ? variant + "/" : ""}$difficulty.json', null);
136136
}
137137

138138
public static function character(character:String):String {

source/funkin/backend/chart/Chart.hx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -139,16 +139,19 @@ class Chart {
139139
}
140140
}
141141

142-
if (includeMetaVariations & data.variants.length > 0) for (variant in data.variants) {
142+
data.metas = [];
143+
if (includeMetaVariations && data.variants.length > 0) for (variant in data.variants) {
143144
if (!data.metas.exists(variant) && Assets.exists(Paths.file('songs/$songName/meta-$variant.json')))
144145
data.metas.set(variant, loadChartMeta(songName, variant, fromMods));
145146
}
146147

147148
return data;
148149
}
149150

150-
public static function parse(songName:String, ?variant:String):ChartData {
151-
var chartPath = Paths.chart(songName, variant);
151+
public static function parse(songName:String, ?difficulty:String, ?variant:String):ChartData {
152+
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
153+
154+
var chartPath = Paths.chart(songName, difficulty, variant);
152155
var base:ChartData = {
153156
strumLines: [],
154157
noteTypes: [],
@@ -162,7 +165,7 @@ class Chart {
162165
fromMods: Paths.assetsTree.existsSpecific(chartPath, "TEXT", MODS)
163166
};
164167

165-
var valid:Bool = true, namePrint = (variant == null || variant == '') ? '$songName' : '$songName ($variant)';
168+
var valid:Bool = true, namePrint = '$songName $difficulty' + ((variant != null && variant != '') ? ' ($variant)' : '');
166169
if (!Assets.exists(chartPath)) {
167170
Logs.error('Chart for song $namePrint at "$chartPath" was not found.');
168171
valid = false;
@@ -256,22 +259,33 @@ class Chart {
256259
if (difficulty == null) difficulty = Flags.DEFAULT_DIFFICULTY;
257260
if (saveSettings == null) saveSettings = {};
258261

259-
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents);
262+
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents && saveSettings.seperateGlobalEvents != true);
260263

261264
#if sys
262-
var songPath = saveSettings.songFolder == null ? 'assets/songs/${chart.meta.name}' : saveSettings.songFolder;
265+
var prefix = 'assets/songs/', assetsRoot = Paths.getAssetsRoot() + '/';
266+
var songPath = saveSettings.songFolder == null ? '${chart.meta.name}' : saveSettings.songFolder, prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null;
263267
var metaPath = '$songPath/meta.json', temp:String;
264-
if ((temp = Paths.assetsTree.getPath(metaPath)) != null) metaPath = temp;
268+
if ((temp = Paths.assetsTree.getPath(prefix + metaPath)) != null) metaPath = temp;
269+
else metaPath = assetsRoot + metaPath;
265270

266271
var chartFolder = saveSettings.folder == null ? ((variant == null || variant == '') ? 'charts' : 'charts/$variant') : saveSettings.folder;
267272
var chartPath = '$songPath/$chartFolder/${difficulty.trim()}.json';
268-
if ((temp = Paths.assetsTree.getPath(chartPath)) != null) chartPath = temp;
273+
if ((temp = Paths.assetsTree.getPath(prefix + chartPath)) != null) chartPath = temp;
274+
else chartPath = assetsRoot + chartPath;
269275

270276
if (saveSettings.saveChart == null || saveSettings.saveChart == true)
271-
CoolUtil.safeSaveFile(chartPath, Json.stringify(filteredChart, null, saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null));
277+
CoolUtil.safeSaveFile(chartPath, Json.stringify(filteredChart, null, prettyPrint));
278+
279+
if (saveSettings.overrideExistingMeta || !FileSystem.exists(metaPath))
280+
CoolUtil.safeSaveFile(metaPath, Json.stringify(filterMetaForSaving(chart.meta), null, prettyPrint));
272281

273-
if (filteredChart.meta != null && (saveSettings.overrideExistingMeta || !FileSystem.exists(metaPath)))
274-
CoolUtil.safeSaveFile(metaPath, makeMetaSaveable(filteredChart.meta));
282+
if (saveSettings.seperateGlobalEvents == true) {
283+
var eventsPath = '$songPath/events.json';
284+
if ((temp = Paths.assetsTree.getPath(prefix + eventsPath)) != null) eventsPath = temp;
285+
else eventsPath = assetsRoot + eventsPath;
286+
287+
CoolUtil.safeSaveFile(eventsPath, Json.stringify({events: filterEventsForSaving(chart.events, false, true)}, null, prettyPrint));
288+
}
275289
#end
276290

277291
return filteredChart;
@@ -304,10 +318,10 @@ class Chart {
304318
var data = [];
305319
if (!saveLocalEvents && !saveGlobalEvents) return data;
306320

307-
for (event in chart.events) if ((saveLocalEvents && event.global != true) || (saveGlobalEvents && event.global == true)) {
321+
for (event in events) if ((saveLocalEvents && event.global != true) || (saveGlobalEvents && event.global == true)) {
308322
var copy = Reflect.copy(event);
309323
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
310-
data.events.push(copy);
324+
data.push(copy);
311325
}
312326

313327
return data;

source/funkin/backend/scripting/events/menu/freeplay/FreeplaySongSelectEvent.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ final class FreeplaySongSelectEvent extends CancellableEvent {
99
* Difficulty name
1010
*/
1111
public var difficulty:String;
12+
/**
13+
* Variation Name
14+
*/
15+
public var variant:String;
1216
/**
1317
* Whenever opponent mode is enabled or not.
1418
*/

source/funkin/backend/system/macros/FunkinSaveMacro.hx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ class FunkinSaveMacro {
4343
* SAVE FUNCTION
4444
*/
4545
var saveFuncBlocks:Array<Expr> = [for(f in fieldNames) macro $i{saveFieldName}.data.$f = $i{f}];
46-
47-
saveFuncBlocks.push(macro $i{"__flush"}());
4846
saveFuncBlocks.push(macro $i{saveFieldName}.flush());
4947

5048
fields.push({
@@ -60,6 +58,8 @@ class FunkinSaveMacro {
6058
access: [APublic, AStatic]
6159
});
6260

61+
var loadFuncBlocks:Array<Expr> = [for(f in fieldNames) macro if ($i{saveFieldName}.data.$f != null) $i{f} = $i{saveFieldName}.data.$f];
62+
6363
/**
6464
* LOAD FUNCTION
6565
*/
@@ -70,10 +70,7 @@ class FunkinSaveMacro {
7070
args: [],
7171
expr: {
7272
pos: Context.currentPos(),
73-
expr: EBlock([for(f in fieldNames)
74-
macro if ($i{saveFieldName}.data.$f != null)
75-
$i{f} = $i{saveFieldName}.data.$f
76-
, macro $i{"__load"}()])
73+
expr: EBlock(loadFuncBlocks)
7774
}
7875
}),
7976
access: [APublic, AStatic]

source/funkin/editors/charter/Charter.hx

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import flixel.util.FlxColor;
2828
class Charter extends UIState {
2929
public static var __song:String;
3030
static var __diff:String;
31+
static var __variant:String;
3132
static var __reload:Bool;
3233

3334
var chart(get, never):ChartData;
@@ -114,11 +115,12 @@ class Charter extends UIState {
114115
private var SONGPOSINFO_BPM = TU.getRaw("songPosInfo.bpm");
115116
private var SONGPOSINFO_TIMESIGNATURE = TU.getRaw("songPosInfo.timeSignature");
116117

117-
public function new(song:String, diff:String, reload:Bool = true) {
118+
public function new(song:String, diff:String, variant:String, reload:Bool = true) {
118119
super();
119120
if (song != null) {
120121
__song = song;
121122
__diff = diff;
123+
__variant = variant;
122124
__reload = reload;
123125
}
124126
}
@@ -578,7 +580,7 @@ class Charter extends UIState {
578580
dataDisplay.screenCenter(Y);
579581
dataDisplay.cameras = [charterCamera]; dataDisplay.x = -dataDisplay.width; add(dataDisplay);*/
580582

581-
DiscordUtil.call("onEditorLoaded", ["Chart Editor", __song + " (" + __diff + ")"]);
583+
DiscordUtil.call("onEditorLoaded", ["Chart Editor", __song + " (" + __diff + ")" + (__variant != null && __variant != "" ? " (" + __variant + ")" : "")]);
582584
}
583585

584586
override function destroy() {
@@ -595,7 +597,7 @@ class Charter extends UIState {
595597
public function loadSong() {
596598
if (__reload) {
597599
EventsData.reloadEvents();
598-
PlayState.loadSong(__song, __diff, false, false);
600+
PlayState.loadSong(__song, __diff, __variant, false, false);
599601
__resetStatics();
600602
}
601603
Conductor.setupSong(PlayState.SONG);
@@ -788,12 +790,13 @@ class Charter extends UIState {
788790
autoSaveTimer = Options.charterAutoSaveTime;
789791
if (!autoSaveNotif.cancelled) {
790792
buildChart();
791-
var songPath:String = '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}';
792793

793794
if (Options.charterAutoSavesSeparateFolder)
794-
Chart.save(songPath, PlayState.SONG, __autoSaveLocation, {saveMetaInChart: true, saveLocalEvents: true, saveGlobalEvents: true, folder: "autosaves", prettyPrint: Options.editorCharterPrettyPrint});
795-
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
796-
Chart.save(songPath, PlayState.SONG, __diff.toLowerCase(), {saveMetaInChart: true, saveLocalEvents: true, saveGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
795+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __autoSaveLocation, {saveMetaInChart: true, saveLocalEvents: true, seperateGlobalEvents: true, folder: 'autosaves', prettyPrint: Options.editorCharterPrettyPrint});
796+
else
797+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: true, saveLocalEvents: true, seperateGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
798+
799+
FlxG.sound.play(Paths.sound('editors/save'));
797800
undos.save();
798801
}
799802
autoSaveNotif.cancelled = false;
@@ -1476,8 +1479,8 @@ class Charter extends UIState {
14761479

14771480
public static function saveChart(shouldBuild:Bool = true, withEvents:Bool = true) {
14781481
#if sys
1479-
FlxG.sound.play(Paths.sound('editors/save'));
1480-
saveTo('${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}', !withEvents, shouldBuild);
1482+
if (shouldBuild && instance != null) instance.buildChart();
1483+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: false, saveLocalEvents: withEvents, prettyPrint: Options.editorCharterPrettyPrint});
14811484
if (undos != null) undos.save();
14821485
#else
14831486
saveChartAs(shouldBuild, withEvents);
@@ -1493,21 +1496,17 @@ class Charter extends UIState {
14931496

14941497
public static function saveEvents(shouldBuild:Bool = true) {
14951498
#if sys
1496-
FlxG.sound.play(Paths.sound('editors/save'));
14971499
if (shouldBuild && instance != null) instance.buildChart();
1498-
var data = {events: Chart.filterChartForSaving(PlayState.SONG, false, false, true).events};
1499-
1500-
var path = '${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}/events.json';
1501-
if (data.events != null && data.events.length > 0) CoolUtil.safeSaveFile(path, Json.stringify(data, null, Options.editorCharterPrettyPrint ? Flags.JSON_PRETTY_PRINT : null));
1502-
else if (FileSystem.exists(path)) FileSystem.deleteFile(path); // Instead of replacing with a useless empty file, deletes the file directly - Nex
1500+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveChart: false, seperateGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
1501+
if (undos != null) undos.save();
15031502
#else
15041503
saveEventsAs(shouldBuild);
15051504
#end
15061505
}
15071506

15081507
public static function saveEventsAs(shouldBuild:Bool = true) {
15091508
if (shouldBuild && instance != null) instance.buildChart();
1510-
var data = {events: Chart.filterChartForSaving(PlayState.SONG, false, false, true).events};
1509+
var data = {events: Chart.filterEventsForSaving(PlayState.SONG.events, false, true)};
15111510

15121511
saveAs(data, null, Options.editorCharterPrettyPrint ? Flags.JSON_PRETTY_PRINT : null, {
15131512
defaultSaveFile: 'events.json'
@@ -1516,12 +1515,8 @@ class Charter extends UIState {
15161515

15171516
public static function saveMeta(shouldBuild:Bool = true) {
15181517
#if sys
1519-
FlxG.sound.play(Paths.sound('editors/save'));
15201518
if (shouldBuild && instance != null) instance.buildChart();
1521-
CoolUtil.safeSaveFile(
1522-
'${Paths.getAssetsRoot()}/songs/${__song.toLowerCase()}/meta.json',
1523-
Json.stringify(PlayState.SONG.meta == null ? {} : Chart.filterChartForSaving(PlayState.SONG, true, false, false).meta, null, Flags.JSON_PRETTY_PRINT)
1524-
);
1519+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveChart: false, overrideExistingMeta: true, prettyPrint: true});
15251520
#else
15261521
saveMetaAs(shouldBuild);
15271522
#end
@@ -1545,9 +1540,7 @@ class Charter extends UIState {
15451540
}, null, shouldBuild);
15461541
}
15471542

1548-
public static function saveAs(data:Dynamic, ?replacer:(key:Dynamic, value:Dynamic) -> Dynamic, ?space:String, ?options:SaveSubstate.SaveSubstateData, ?saveOptions:Map<String, Bool>, shouldBuild:Bool = true) {
1549-
FlxG.sound.play(Paths.sound('editors/save'));
1550-
if (shouldBuild && instance != null) instance.buildChart();
1543+
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();
15511544
var cur = FlxG.state;
15521545
while(true) {
15531546
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 {
15581551
#if sys
15591552
public static function saveTo(path:String, separateEvents:Bool = false, shouldBuild:Bool = true) {
15601553
if (shouldBuild && instance != null) instance.buildChart();
1561-
Chart.save(path, PlayState.SONG, __diff.toLowerCase(), {saveMetaInChart: false, saveLocalEvents: !separateEvents, prettyPrint: Options.editorCharterPrettyPrint});
1554+
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: false, saveLocalEvents: !separateEvents, songFolder: path, prettyPrint: Options.editorCharterPrettyPrint});
15621555
}
15631556
#end
15641557
#end
@@ -1570,17 +1563,17 @@ class Charter extends UIState {
15701563
else {undos = null; FlxG.switchState(new CharterSelection()); Charter.instance.__clearStatics();}
15711564
}
15721565

1573-
function _file_save_all(_) saveEverything();
1574-
function _file_save(_) saveChart();
1575-
function _file_saveas(_) saveChartAs();
1576-
function _file_events_save(_) saveEvents();
1577-
function _file_events_saveas(_) saveEventsAs();
1578-
function _file_save_no_events(_) saveChart(true, false);
1579-
function _file_saveas_no_events(_) saveChartAs(true, false);
1580-
function _file_meta_save(_) saveMeta();
1581-
function _file_meta_saveas(_) saveMetaAs();
1582-
function _file_saveas_fnflegacy(_) saveLegacyChartAs();
1583-
function _file_saveas_psych(_) savePsychChartAs();
1566+
function _file_save_all(_) {saveEverything(); FlxG.sound.play(Paths.sound('editors/save'));}
1567+
function _file_save(_) {saveChart(); FlxG.sound.play(Paths.sound('editors/save'));}
1568+
function _file_saveas(_) {saveChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
1569+
function _file_events_save(_) {saveEvents(); FlxG.sound.play(Paths.sound('editors/save'));}
1570+
function _file_events_saveas(_) {saveEventsAs(); FlxG.sound.play(Paths.sound('editors/save'));}
1571+
function _file_save_no_events(_) {saveChart(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
1572+
function _file_saveas_no_events(_) {saveChartAs(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
1573+
function _file_meta_save(_) {saveMeta(); FlxG.sound.play(Paths.sound('editors/save'));}
1574+
function _file_meta_saveas(_) {saveMetaAs(); FlxG.sound.play(Paths.sound('editors/save'));}
1575+
function _file_saveas_fnflegacy(_) {saveLegacyChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
1576+
function _file_saveas_psych(_) {savePsychChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
15841577

15851578
function _edit_copy(_, playSFX=true) {
15861579
if (playSFX) FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_COPY_SOUND));

source/funkin/editors/charter/CharterSelection.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class CharterSelectionScreen extends EditorTreeMenuScreen {
2626
public var curSong:ChartMetaData;
2727

2828
inline public function makeChartOption(d:String, name:String):TextOption {
29-
return new TextOption(d, getID('acceptDifficulty'), () -> FlxG.switchState(new Charter(name, d)));
29+
return new TextOption(d, getID('acceptDifficulty'), () -> FlxG.switchState(new Charter(name, d, null)));
3030
}
3131

3232
public function makeSongOption(s:ChartMetaData):IconOption {

0 commit comments

Comments
 (0)