Skip to content

Commit f3b9a3f

Browse files
committed
Merge branch 'dev'
2 parents 5eaa1f4 + e647eab commit f3b9a3f

8 files changed

Lines changed: 110 additions & 50 deletions

File tree

CloneDash.Common/HumanLanguage.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public HumanLanguage(ReadOnlySpan<char> code){
2727

2828
public static readonly HumanLanguage Any = new("iv");
2929

30-
public static readonly HumanLanguage Chinese = new("zh");
30+
public static readonly HumanLanguage SimplifiedChinese = new("zh-CN");
31+
public static readonly HumanLanguage TraditionalChinese = new("zh-TW");
3132
public static readonly HumanLanguage English = new("en");
3233
public static readonly HumanLanguage Japanese = new("ja");
3334
public static readonly HumanLanguage Korean = new("ko");

CloneDash.CustomAlbumsCompatibility/CustomAlbums/CustomCharts.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,18 @@ public class MD1_CustomChartsSong : MD1_Song
6565
public MDMCChart WebChart;
6666
public bool UsesWebChart = false;
6767

68-
public MD1_CustomChartsSong(in MDMCChart webChart) : base(null!) {
68+
public MD1_CustomChartsSong(in MDMCChart webChart) : base() {
6969
WebChart = webChart;
7070
UsesWebChart = true;
7171

72-
Name = webChart.TitleRomanized ?? webChart.Title;
73-
Author = webChart.Artist;
72+
AddBaseJSONInfo(new() {
73+
Name = webChart.Title,
74+
Author = webChart.Artist,
75+
});
76+
AddLocalizedJSONInfo(Common.HumanLanguage.English, webChart.TitleRomanized, null);
7477
}
7578

76-
public MD1_CustomChartsSong(string filepath) : base(null!) {
79+
public MD1_CustomChartsSong(string filepath) : base() {
7780
Filepath = filepath;
7881
string? ext = Path.GetExtension(filepath);
7982
switch (ext) {
@@ -89,9 +92,12 @@ public MD1_CustomChartsSong(string filepath) : base(null!) {
8992

9093
default: throw new NotImplementedException("Custom Charts: Bad filetype for CustomChartsSong constructor!");
9194
}
95+
96+
if (Archive != null)
97+
ProduceInfo(); // Produce info now so AddBaseJSONInfo gets what it needs
9298
}
9399

94-
public MD1_CustomChartsSong(string pathID, string path) : base(null!) {
100+
public MD1_CustomChartsSong(string pathID, string path) : base() {
95101
string? ext = Path.GetExtension(path);
96102
switch (ext) {
97103
case ".mdm":
@@ -104,6 +110,9 @@ public MD1_CustomChartsSong(string pathID, string path) : base(null!) {
104110
break;
105111
default: throw new NotImplementedException("Custom Charts: Bad filetype for CustomChartsSong constructor!");
106112
}
113+
114+
if (Archive != null)
115+
ProduceInfo(); // Produce info now so AddBaseJSONInfo gets what it needs
107116
}
108117

109118
~MD1_CustomChartsSong() {
@@ -192,8 +201,11 @@ protected override void ProduceCover(ChartCoverAvailableToMainThreadFn callback)
192201
if (info == null)
193202
return null;
194203

195-
Name = info.name;
196-
Author = info.author;
204+
AddBaseJSONInfo(new() {
205+
Name = info.name,
206+
Author = info.author
207+
});
208+
197209
MD1_SongInfo ret = new() {
198210
BPM = info.bpm,
199211
LevelDesigners = [info.levelDesigner1, info.levelDesigner2, info.levelDesigner3, info.levelDesigner4],
@@ -288,7 +300,7 @@ private MD1_CustomAlbumsChart loadFromStream(Stream map, int difficulty = 0) {
288300
Interlude.Spin(submessage: "Reading Custom Albums chart...");
289301
if (bms == null) throw new Exception("BMS parsing exception");
290302
var stageInfo = BmsLoader.TransmuteData(bms);
291-
stageInfo.mapName = Name;
303+
stageInfo.mapName = FetchMetadata().Name;
292304
stageInfo.difficulty = difficulty;
293305
stageInfo.scene = bms.Info["GENRE"]?.GetValue<string>() ?? string.Empty;
294306
stageInfo.bpm = bms.Bpm;

CloneDash.MuseDash1Compatibility/Compatibility/MD1_Song.cs

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Nucleus;
1212
using Nucleus.Audio;
1313
using Nucleus.Common.Audio;
14+
using Nucleus.Types;
1415
using OdinSerializer;
1516
using Raylib_cs;
1617
using System.Collections.Concurrent;
@@ -41,6 +42,24 @@ public class MuseDashSongInfoJSON
4142
[JsonPropertyName("difficulty3")] public string Difficulty3 { get; set; } = "";
4243
[JsonPropertyName("difficulty4")] public string Difficulty4 { get; set; } = "";
4344
[JsonPropertyName("difficulty5")] public string Difficulty5 { get; set; } = "";
45+
46+
public void CloneInto(MuseDashSongInfoJSON into) {
47+
into.UID = UID;
48+
into.Name = Name;
49+
into.Author = Author;
50+
into.BPM = BPM;
51+
into.Music = Music;
52+
into.Demo = Demo;
53+
into.Cover = Cover;
54+
into.NoteJSON = NoteJSON;
55+
into.Scene = Scene;
56+
into.LevelDesigner = LevelDesigner;
57+
into.Difficulty1 = Difficulty1;
58+
into.Difficulty2 = Difficulty2;
59+
into.Difficulty3 = Difficulty3;
60+
into.Difficulty4 = Difficulty4;
61+
into.Difficulty5 = Difficulty5;
62+
}
4463
}
4564

4665
public delegate void ChartCoverAvailableToMainThreadFn(MD1_SongCover? cover);
@@ -52,8 +71,6 @@ public class MD1_Song : ISong, IHasLowToHighDifficulties
5271

5372
public MD1_SongInfo? Info;
5473

55-
public string Name = "";
56-
public string Author = "";
5774

5875
protected IAudioClip? AudioTrack;
5976
protected IAudioClip? DemoTrack;
@@ -194,20 +211,25 @@ public List<MD1_SongChart> LoadSheets() {
194211
return null;
195212
}
196213

214+
public SongMetadata FetchMetadata() => FetchMetadata(HumanLanguage.GetCurrentLanguage());
197215
public SongMetadata FetchMetadata(HumanLanguage desiredLanguage) {
198-
GetInfo(); // This is annoying: it fixes an issue with custom albums, didnt feel like it would be a good idea to differentiate them though..
199-
// TODO: language
200-
return new() {
201-
Name = Name,
202-
Author = Author
203-
};
216+
if (__jsonInfoLanguages.TryGetValue(desiredLanguage, out MuseDashSongInfoJSON? languageInfo))
217+
return new() {
218+
Name = languageInfo.Name ?? __jsonInfo.Name,
219+
Author = languageInfo.Author ?? __jsonInfo.Author
220+
};
221+
else
222+
return new() {
223+
Name = __jsonInfo.Name,
224+
Author = __jsonInfo.Author
225+
};
204226
}
205227

206228
public IReadOnlyList<ISongChart> GetCharts() => LoadSheets();
207229
public bool IsAsynchronouslyLoading() => DeferringDemoToAsyncHandler;
208230
public void WaitForAsynchronousLoad(OnAsynchronousLoadingCompleteFn callback) => throw new NotImplementedException();
209231

210-
public IAudioClip? GetDemoAudio(){
232+
public IAudioClip? GetDemoAudio() {
211233
return GetDemoTrack();
212234
}
213235
public SongCoverInfo GetCoverTexture() {
@@ -230,11 +252,20 @@ public SongCoverInfo GetCoverTexture() {
230252
});
231253
}
232254

233-
private MuseDashSongInfoJSON __jsonInfo;
234-
public MD1_Song(MuseDashSongInfoJSON info) {
235-
__jsonInfo = info;
236-
// Debug.Assert(info.Difficulty5 == "");
255+
private readonly MuseDashSongInfoJSON __jsonInfo = new();
256+
private readonly Dictionary<HumanLanguage, MuseDashSongInfoJSON> __jsonInfoLanguages = [];
257+
258+
public void AddBaseJSONInfo(MuseDashSongInfoJSON baseInfo) {
259+
baseInfo.CloneInto(__jsonInfo);
260+
}
261+
262+
public void AddLocalizedJSONInfo(HumanLanguage lang, string? name, string? author) {
263+
__jsonInfoLanguages[lang] = new() {
264+
Name = name!,
265+
Author = author!
266+
};
237267
}
268+
238269
public static string? GetFixedFilename(string givenBase, string fileName, [NotNullWhen(true)] bool throwExp = true) {
239270
return
240271
MuseDash1Compatibility.StreamingFiles.FirstOrDefault(x => x.Contains(fileName.Replace("{name}", givenBase)))
@@ -248,7 +279,10 @@ public MD1_Song(MuseDashSongInfoJSON info) {
248279

249280
[JsonIgnore]
250281
public string BaseName => GetInfo()!.Music.Substring(0, GetInfo()!.Music.Length - 6);
251-
public override string ToString() => $"{Name} by {Author}";
282+
public override string ToString() {
283+
SongMetadata metadata = FetchMetadata();
284+
return $"{metadata.Name} by {metadata.Author}";
285+
}
252286

253287

254288
public AssetsManager AssetsFile { get; private set; } = null;
@@ -269,7 +303,7 @@ private void LoadAssetFile() {
269303
DemoFile = new();
270304
DemoFile.LoadFiles(filepath);
271305
}
272-
else Logs.Warn($"CloneDash: MuseDashSong.LoadAssetFile could not generate a demo filepath for {Name}.");
306+
else Logs.Warn($"CloneDash: MuseDashSong.LoadAssetFile could not generate a demo filepath for {__jsonInfo.Name}.");
273307
}
274308
}
275309

@@ -334,7 +368,7 @@ protected virtual void ProduceCover(ChartCoverAvailableToMainThreadFn callback)
334368
if (DashSheetOverrides.TryGetValue(mapID, out MD1_SongChart? sheet))
335369
return sheet;
336370

337-
LoadAssetFile();
371+
LoadAssetFile();
338372
Interlude.Spin();
339373

340374
MD1_SongChart chart = new MD1_SongChart(this, mapID);
@@ -344,7 +378,7 @@ protected virtual void ProduceCover(ChartCoverAvailableToMainThreadFn callback)
344378
/// <summary>
345379
/// Called from charts only!!!
346380
/// </summary>
347-
public virtual MD1_GamemodeData? ProduceGamemodeData(MD1_SongChart chart, int mapID){
381+
public virtual MD1_GamemodeData? ProduceGamemodeData(MD1_SongChart chart, int mapID) {
348382
//MonoBehaviour map = (MonoBehaviour)AssetsFile.assetsFileList[0].Objects.First(x => x is MonoBehaviour mB && mB.m_Name.EndsWith($"_map{mapID}"));
349383
MonoBehaviour? map = MuseDash1Compatibility.StreamingAssets.LoadAsset<MonoBehaviour>($"Assets/Static Resources/Data/Configs/StageInfos/{__jsonInfo.NoteJSON}{mapID}.asset").GetResult();
350384
if (map == null)
@@ -373,9 +407,6 @@ protected virtual void ProduceCover(ChartCoverAvailableToMainThreadFn callback)
373407
protected virtual MD1_SongInfo? ProduceInfo() {
374408
List<string> SearchTags = [];
375409

376-
Name = __jsonInfo.Name;
377-
Author = __jsonInfo.Author;
378-
379410
SearchTags.AddRange(__jsonInfo.Name.Split(' '));
380411
MD1_SongInfo info = new MD1_SongInfo() {
381412
BPM = __jsonInfo.BPM,
@@ -399,4 +430,11 @@ protected virtual void ProduceCover(ChartCoverAvailableToMainThreadFn callback)
399430
bool IHasLowToHighDifficulties.GetDifficulties(Span<int> difficulties) {
400431
return Difficulties.AsSpan().TryCopyTo(difficulties);
401432
}
433+
434+
public IEnumerable<MuseDashSongInfoJSON> GetAvailableInfo() {
435+
if (__jsonInfo != null)
436+
yield return __jsonInfo;
437+
foreach (var info in __jsonInfoLanguages)
438+
yield return info.Value;
439+
}
402440
}

CloneDash.MuseDash1Compatibility/Compatibility/MuseDash1Compatibility.cs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// TODO: this file is WAY too bloated!!!
22

33
using AssetStudio;
4+
using CloneDash.Common;
45
using CloneDash.Common.Data;
56
using CloneDash.Common.Gamemodes.MuseDash;
67
using CloneDash.Common.Gamemodes.MuseDash.V1;
@@ -669,6 +670,10 @@ public static void BuildDashStructures() {
669670
// var songsEN_raw = filesystem.ReadAllText("musedash", $"Assets/Static Resources/Data/Configs/english/{album.JsonName}_English.json");
670671
var songs = Filesystem.ReadJSON<List<MuseDashSongInfoJSON>>("musedash", $"Assets/Static Resources/Data/Configs/others/{album.JsonName}.json");
671672
var songsEN = Filesystem.ReadJSON<__musedashSong[]>("musedash", $"Assets/Static Resources/Data/Configs/english/{album.JsonName}_English.json");
673+
var songsCN_S = Filesystem.ReadJSON<__musedashSong[]>("musedash", $"Assets/Static Resources/Data/Configs/chineses/{album.JsonName}_ChineseS.json");
674+
var songsCN_T = Filesystem.ReadJSON<__musedashSong[]>("musedash", $"Assets/Static Resources/Data/Configs/chineset/{album.JsonName}_ChineseT.json");
675+
var songsJP = Filesystem.ReadJSON<__musedashSong[]>("musedash", $"Assets/Static Resources/Data/Configs/japanese/{album.JsonName}_Japanese.json");
676+
var songsKO = Filesystem.ReadJSON<__musedashSong[]>("musedash", $"Assets/Static Resources/Data/Configs/korean/{album.JsonName}_Korean.json");
672677
// Debug.Assert(songs.Count == songsEN.Length);
673678
// if (songs.Count != songsEN.Length) {
674679
// Logs.Print($"inconsistency: {album.JsonName} songs length! songs ({songs.Count}) != songsEN ({songsEN.Length})");
@@ -679,17 +684,19 @@ public static void BuildDashStructures() {
679684

680685
for (int i = 0; i < songs.Count; i++) {
681686
PatchSong(songs, i);
682-
var song = new MD1_Song(songs[i]) {
683-
Name = songsEN[i].name,
684-
Author = songsEN[i].author,
685-
Album = album
686-
};
687+
var song = new MD1_Song();
688+
song.AddBaseJSONInfo(songs[i]);
689+
song.AddLocalizedJSONInfo(HumanLanguage.English, songsEN[i].name, songsEN[i].author);
690+
song.AddLocalizedJSONInfo(HumanLanguage.SimplifiedChinese, songsCN_S[i].name, songsCN_S[i].author);
691+
song.AddLocalizedJSONInfo(HumanLanguage.TraditionalChinese, songsCN_T[i].name, songsCN_T[i].author);
692+
song.AddLocalizedJSONInfo(HumanLanguage.Japanese, songsJP[i].name, songsJP[i].author);
693+
song.AddLocalizedJSONInfo(HumanLanguage.Korean, songsKO[i].name, songsKO[i].author);
687694
workSongs.Add(song);
688695
}
689696
});
690697

691698
Songs = [.. workSongs];
692-
Songs.Sort((x, y) => x.Name.CompareTo(y.Name));
699+
Songs.Sort((x, y) => x.FetchMetadata(HumanLanguage.Any).Name.CompareTo(y.FetchMetadata(HumanLanguage.Any).Name));
693700
#if I_AM_LAZY_I_WANT_TO_KNOW_THIS_NUMBER
694701
Logs.Info($"total songs: {Songs.Count}, charts: {Songs.Sum(x => {
695702
if (x.GetInfo() == null)
@@ -705,11 +712,13 @@ public static void BuildDashStructures() {
705712
#endif
706713
HashSet<char> codepoints = [];
707714
foreach (var song in Songs) {
708-
string name = song.Name, author = song.Author;
709-
for (int i = 0, c = name.Length; i < c; i++)
710-
codepoints.Add(name[i]);
711-
for (int i = 0, c = author.Length; i < c; i++)
712-
codepoints.Add(author[i]);
715+
foreach (MuseDashSongInfoJSON info in song.GetAvailableInfo()) {
716+
string name = info.Name, author = info.Author;
717+
for (int i = 0, c = name.Length; i < c; i++)
718+
codepoints.Add(name[i]);
719+
for (int i = 0, c = author.Length; i < c; i++)
720+
codepoints.Add(author[i]);
721+
}
713722
}
714723
CodepointsInUse = codepoints.ToArray();
715724
}

CloneDash.MuseDash1Compatibility/Game/MuseDash1Game.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ private static void clonedash_openmdlevel_execute(ConCommand cmd, in TokenizedCo
129129
if (song == null) {
130130
Logs.Warn("Can't find that song.");
131131
Logs.Print("Here are some similar names:");
132-
foreach (var s in MuseDash1Compatibility.FindSimilarSongs(md_level))
133-
Logs.Print($" {s.Name} ({s.BaseName})");
132+
foreach (var s in MuseDash1Compatibility.FindSimilarSongs(md_level))
133+
Logs.Print($" {s.FetchMetadata().Name} ({s.BaseName})");
134134
return;
135135
}
136136

@@ -142,7 +142,7 @@ private static void clonedash_openmdlevel_autocomplete(ConCommandBase cmd, strin
142142
if (curArgPos == 1) {
143143
var songs = MuseDash1Compatibility.FindSongsStartingWith(args.Arg(1));
144144
returns = [.. songs.Select(s => s.BaseName)];
145-
returnHelp = [.. songs.Select(s => $" '{s.Name}'")];
145+
returnHelp = [.. songs.Select(s => $" '{s.FetchMetadata().Name}'")];
146146
}
147147
else if (curArgPos == 2) {
148148
var values = Enum.GetValues<MuseDashDifficulty>();
@@ -624,7 +624,7 @@ public override void Initialize(params object[] _) {
624624
using (StaticSequentialProfiler.StartStackFrame("CD_GameLevel.RichPresenceUpdate")) {
625625
RichPresenceSystem.SetPresence(new() {
626626
Details = "In Game",
627-
State = $"Muse Dash 1 - '{gameParameters.Chart?.Song?.Name ?? "<null>"}'"
627+
State = $"Muse Dash 1 - '{gameParameters.Chart?.Song?.FetchMetadata().Name ?? "<null>"}'"
628628
});
629629
}
630630
using (StaticSequentialProfiler.StartStackFrame("CD_GameLevel.PrepareShaders")) {
@@ -1005,8 +1005,8 @@ public override void Think(FrameState frameState) {
10051005
settings.OnButtonClick += delegate (Button self, ButtonCode clickedButton) {
10061006
var panel = new Panel(RootPanel);
10071007
panel.SetPaintBackgroundEnabled(false);
1008-
panel. Anchor = Anchor.Center;
1009-
panel. Origin = Anchor.Center;
1008+
panel.Anchor = Anchor.Center;
1009+
panel.Origin = Anchor.Center;
10101010
panel.DynamicallySized = true;
10111011
panel.Size = new(0.9f);
10121012

CloneDash.MuseDash1Compatibility/Scenes/CloneDashMD1SceneUI.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ public override void Paint(float width, float height) {
104104
var fs = 24;
105105
var y = 0;
106106

107-
Match boldRegexMatch = Util.BoldRegex.Match(chart.Song.Name);
107+
Match boldRegexMatch = Util.BoldRegex.Match(chart.Song.FetchMetadata().Name);
108108
Graphics2D.DrawText(16, 16 + y,
109-
boldRegexMatch.Success ? boldRegexMatch.Groups[1].Value : chart.Song.Name,
109+
boldRegexMatch.Success ? boldRegexMatch.Groups[1].Value : chart.Song.FetchMetadata().Name,
110110
boldRegexMatch.Success ? Graphics2D.UI_MONO_BOLD_FONT_NAME : Graphics2D.UI_CN_JP_FONT_NAME,
111111
fs);
112112
y += fs + 4;

CloneDash/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ private static void LevelTransitions_OnLoadSongSelector(SongSelector selector, C
8383
if (song is MD1_CustomChartsSong customChartsSong) {
8484
customChartsSong.DownloadOrPullFromCache((c) => {
8585
if (EngineCore.Level is not MainMenuLevel mml) {
86-
Logs.Warn($"Downloading custom charts song '{c.Name}' completed downloading in a non-main menu context, ignoring.");
86+
Logs.Warn($"Downloading custom charts song '{c.FetchMetadata().Name}' completed downloading in a non-main menu context, ignoring.");
8787
return;
8888
}
8989

Nucleus.ModelEditor/UI/OutlinerNode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public ITexture? ImageTexture {
114114
set => Image.Texture = value;
115115
}
116116
public Color ImageColor {
117-
get => Image.ImageColor1;
117+
get => Image.ImageColor;
118118
set => Image.ImageColor = value;
119119
}
120120

0 commit comments

Comments
 (0)