Add project files.
This commit is contained in:
9
Assets/Cryville/Crtr/Extensions/Malody.meta
Normal file
9
Assets/Cryville/Crtr/Extensions/Malody.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfd44d1c0681e4842a1f031556519042
|
||||
folderAsset: yes
|
||||
timeCreated: 1637936550
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
243
Assets/Cryville/Crtr/Extensions/Malody/MalodyChartConverter.cs
Normal file
243
Assets/Cryville/Crtr/Extensions/Malody/MalodyChartConverter.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using Cryville.Crtr.Browsing;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Crtr.Extensions.Malody {
|
||||
public class MalodyChartConverter : ResourceConverter {
|
||||
static readonly string[] SUPPORTED_FORMATS = { ".mc", ".mcz" };
|
||||
static readonly string[] MODES = { "key", "step", "dj", "catch", "pad", "taiko", "ring", "slide", "live" };
|
||||
|
||||
public override string[] GetSupportedFormats() {
|
||||
return SUPPORTED_FORMATS;
|
||||
}
|
||||
|
||||
public override IEnumerable<Resource> ConvertFrom(FileInfo file) {
|
||||
List<Resource> result = new List<Resource>();
|
||||
MalodyChart src;
|
||||
using (var reader = new StreamReader(file.FullName)) {
|
||||
src = JsonConvert.DeserializeObject<MalodyChart>(reader.ReadToEnd());
|
||||
}
|
||||
if (src.meta.mode != 0) throw new NotImplementedException("The chart mode is not supported");
|
||||
|
||||
ChartMeta meta = new ChartMeta() {
|
||||
song = new ChartMeta.MetaInfo() {
|
||||
name = src.meta.song.titleorg != null ? src.meta.song.titleorg : src.meta.song.title,
|
||||
author = src.meta.song.artistorg != null ? src.meta.song.artistorg : src.meta.song.artist,
|
||||
},
|
||||
ruleset = "malody!" + MODES[src.meta.mode],
|
||||
};
|
||||
|
||||
Chart chart = new Chart {
|
||||
format = 1,
|
||||
time = new BeatTime(-4, 0, 1),
|
||||
ruleset = "malody!" + MODES[src.meta.mode],
|
||||
sigs = new List<Chart.Signature>(),
|
||||
sounds = new List<Chart.Sound>(),
|
||||
motions = new List<Chart.Motion>(),
|
||||
groups = new List<Chart.Group>(),
|
||||
};
|
||||
var group = new Chart.Group() {
|
||||
tracks = new List<Chart.Track>(),
|
||||
notes = new List<Chart.Note>(),
|
||||
motions = new List<Chart.Motion> {
|
||||
new Chart.Motion() { motion = "dir#0:-50,," },
|
||||
new Chart.Motion() { motion = "dist:5h" },
|
||||
new Chart.Motion() { motion = "visible:1" },
|
||||
},
|
||||
};
|
||||
chart.groups.Add(group);
|
||||
int col = src.meta.mode_ext.column;
|
||||
for (int i = 0; i < col; i++) {
|
||||
group.tracks.Add(new Chart.Track {
|
||||
motions = new List<Chart.Motion> {
|
||||
new Chart.Motion() { motion = "pt:" + ((i + 0.5) / col * 0.9 - 0.45).ToString() + "w,-.35h" },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
IEnumerable<MalodyChart.IEvent> events = src.time.Cast<MalodyChart.IEvent>();
|
||||
if (src.effect != null) events = events.Concat(src.effect.Cast<MalodyChart.IEvent>());
|
||||
events = events.Concat(src.note.Cast<MalodyChart.IEvent>());
|
||||
List<MalodyChart.IEvent> endEvents = new List<MalodyChart.IEvent>();
|
||||
foreach (var ev in events)
|
||||
if (ev.endbeat != null)
|
||||
endEvents.Add(new MalodyChart.EndEvent {
|
||||
beat = ev.endbeat,
|
||||
StartEvent = ev,
|
||||
});
|
||||
events = events.Concat(endEvents)
|
||||
.OrderBy(e => e.beat[0] + (float)e.beat[1] / e.beat[2])
|
||||
.ThenBy(e => e.Priority);
|
||||
|
||||
Dictionary<MalodyChart.IEvent, StartEventState> longEvents
|
||||
= new Dictionary<MalodyChart.IEvent, StartEventState>();
|
||||
|
||||
float? baseBpm = null;
|
||||
float pbeat = 0f, ctime = 0f;
|
||||
int[] endbeat = new int[] { 0, 0, 1 };
|
||||
foreach (var ev in events) {
|
||||
float cbeat = bp(ev.beat);
|
||||
ctime += baseBpm == null ? 0 : (cbeat - pbeat) / baseBpm.Value * 60f;
|
||||
pbeat = cbeat;
|
||||
if (ev is MalodyChart.Time) {
|
||||
var tev = (MalodyChart.Time)ev;
|
||||
if (baseBpm == null) baseBpm = tev.bpm;
|
||||
chart.sigs.Add(new Chart.Signature {
|
||||
time = new BeatTime(ev.beat[0], ev.beat[1], ev.beat[2]),
|
||||
tempo = tev.bpm,
|
||||
});
|
||||
chart.motions.Add(new Chart.Motion {
|
||||
time = new BeatTime(ev.beat[0], ev.beat[1], ev.beat[2]),
|
||||
motion = "svm:" + (tev.bpm / baseBpm).ToString()
|
||||
});
|
||||
}
|
||||
else if (ev is MalodyChart.Effect) {
|
||||
var tev = (MalodyChart.Effect)ev;
|
||||
if (tev.scroll != null) group.motions.Add(new Chart.Motion {
|
||||
time = new BeatTime(ev.beat[0], ev.beat[1], ev.beat[2]),
|
||||
motion = "svm:" + tev.scroll.ToString()
|
||||
});
|
||||
}
|
||||
else if (ev is MalodyChart.Note) {
|
||||
var tev = (MalodyChart.Note)ev;
|
||||
if (tev.type == 1) {
|
||||
if (tev.beat[0] == 0 && tev.beat[1] == 0) {
|
||||
result.Add(new SongResource(meta.song.name, new FileInfo(file.DirectoryName + "/" + tev.sound)));
|
||||
chart.sounds.Add(new Chart.Sound {
|
||||
time = new BeatTime(0, 0, 1),
|
||||
id = meta.song.name,
|
||||
offset = -tev.offset / 1000f,
|
||||
});
|
||||
}
|
||||
else throw new NotImplementedException();
|
||||
}
|
||||
else {
|
||||
if (bp(tev.beat) > bp(endbeat)) endbeat = tev.beat;
|
||||
var rn = new Chart.Note() {
|
||||
time = new BeatTime(tev.beat[0], tev.beat[1], tev.beat[2]),
|
||||
judge = "normal",
|
||||
motions = new List<Chart.Motion> {
|
||||
new Chart.Motion() { motion = "track:" + tev.column.ToString() }
|
||||
},
|
||||
};
|
||||
if (tev.endbeat != null) {
|
||||
if (bp(tev.endbeat) > bp(endbeat)) endbeat = tev.endbeat;
|
||||
rn.endtime = new BeatTime(tev.endbeat[0], tev.endbeat[1], tev.endbeat[2]);
|
||||
rn.endjudge = "longend";
|
||||
longEvents.Add(ev, new StartEventState {
|
||||
Destination = rn,
|
||||
Time = ctime,
|
||||
});
|
||||
}
|
||||
group.notes.Add(rn);
|
||||
}
|
||||
}
|
||||
else if (ev is MalodyChart.EndEvent) {
|
||||
var tev = (MalodyChart.EndEvent)ev;
|
||||
if (tev.StartEvent is MalodyChart.Note) {
|
||||
var sev = tev.StartEvent;
|
||||
var state = longEvents[sev];
|
||||
var dest = (Chart.Note)state.Destination;
|
||||
dest.motions.Add(new Chart.Motion() {
|
||||
time = new BeatTime(sev.beat[0], sev.beat[1], sev.beat[2]),
|
||||
endtime = new BeatTime(ev.beat[0], ev.beat[1], ev.beat[2]),
|
||||
motion = "judge!long:" + ((ctime - state.Time) * 20).ToString(),
|
||||
});
|
||||
longEvents.Remove(sev);
|
||||
}
|
||||
else throw new NotSupportedException();
|
||||
}
|
||||
else throw new NotSupportedException();
|
||||
}
|
||||
chart.endtime = new BeatTime(endbeat[0] + 4, endbeat[1], endbeat[2]);
|
||||
meta.chart = new ChartMeta.MetaInfo() {
|
||||
name = src.meta.version,
|
||||
author = src.meta.creator,
|
||||
length = ctime,
|
||||
};
|
||||
meta.note_count = group.notes.Count;
|
||||
string chartName = string.Format("{0} - {1}", meta.song.name, meta.chart.name);
|
||||
result.Add(new ChartResource(chartName, chart, meta));
|
||||
if (src.meta.background != null)
|
||||
result.Add(new CoverResource(chartName, new FileInfo(file.DirectoryName + "/" + src.meta.background)));
|
||||
return result;
|
||||
}
|
||||
|
||||
struct StartEventState {
|
||||
public float Time { get; set; }
|
||||
public ChartEvent Destination { get; set; }
|
||||
}
|
||||
|
||||
float bp(int[] beat) {
|
||||
return beat[0] + (float)beat[1] / beat[2];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE1006
|
||||
public struct MalodyChart {
|
||||
public interface IEvent {
|
||||
int[] beat { get; set; }
|
||||
int[] endbeat { get; set; }
|
||||
int Priority { get; }
|
||||
}
|
||||
public struct EndEvent : IEvent {
|
||||
public int[] beat { get; set; }
|
||||
public int[] endbeat { get; set; }
|
||||
public IEvent StartEvent { get; set; }
|
||||
public int Priority { get { return StartEvent.Priority - 1; } }
|
||||
}
|
||||
|
||||
public Meta meta;
|
||||
public struct Meta {
|
||||
public SongInfo song;
|
||||
public struct SongInfo {
|
||||
public string title;
|
||||
public string artist;
|
||||
public string titleorg;
|
||||
public string artistorg;
|
||||
}
|
||||
|
||||
public string background;
|
||||
|
||||
public string creator;
|
||||
public string version;
|
||||
|
||||
public int mode;
|
||||
public ModeExt mode_ext;
|
||||
public struct ModeExt {
|
||||
public int column;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Time> time;
|
||||
public struct Time : IEvent {
|
||||
public int[] beat { get; set; }
|
||||
public int[] endbeat { get; set; }
|
||||
public float bpm;
|
||||
public int Priority { get { return -2; } }
|
||||
}
|
||||
|
||||
public List<Effect> effect;
|
||||
public struct Effect : IEvent {
|
||||
public int[] beat { get; set; }
|
||||
public int[] endbeat { get; set; }
|
||||
public float? scroll;
|
||||
public int Priority { get { return 0; } }
|
||||
}
|
||||
|
||||
public List<Note> note;
|
||||
public struct Note : IEvent {
|
||||
public int[] beat { get; set; }
|
||||
public int[] endbeat { get; set; }
|
||||
public int column;
|
||||
public string sound;
|
||||
public int offset;
|
||||
public int type;
|
||||
public int Priority { get { return 0; } }
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3624013a6911ba45933085332724ff1
|
||||
timeCreated: 1637936498
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user