Merge branch 'rewrite/master' into feature/chart-editor-context-menus
This commit is contained in:
@@ -4,6 +4,7 @@ import funkin.data.event.SongEventRegistry;
|
||||
import funkin.data.event.SongEventSchema;
|
||||
import funkin.data.song.SongRegistry;
|
||||
import thx.semver.Version;
|
||||
import funkin.util.tools.ICloneable;
|
||||
|
||||
/**
|
||||
* Data containing information about a song.
|
||||
@@ -11,7 +12,7 @@ import thx.semver.Version;
|
||||
* Data which is only necessary in-game should be stored in the SongChartData.
|
||||
*/
|
||||
@:nullSafety
|
||||
class SongMetadata
|
||||
class SongMetadata implements ICloneable<SongMetadata>
|
||||
{
|
||||
/**
|
||||
* A semantic versioning string for the song data format.
|
||||
@@ -86,16 +87,16 @@ class SongMetadata
|
||||
* @param newVariation Set to a new variation ID to change the new metadata.
|
||||
* @return The cloned SongMetadata
|
||||
*/
|
||||
public function clone(?newVariation:String = null):SongMetadata
|
||||
public function clone():SongMetadata
|
||||
{
|
||||
var result:SongMetadata = new SongMetadata(this.songName, this.artist, newVariation == null ? this.variation : newVariation);
|
||||
var result:SongMetadata = new SongMetadata(this.songName, this.artist, this.variation);
|
||||
result.version = this.version;
|
||||
result.timeFormat = this.timeFormat;
|
||||
result.divisions = this.divisions;
|
||||
result.offsets = this.offsets;
|
||||
result.timeChanges = this.timeChanges;
|
||||
result.offsets = this.offsets.clone();
|
||||
result.timeChanges = this.timeChanges.deepClone();
|
||||
result.looped = this.looped;
|
||||
result.playData = this.playData;
|
||||
result.playData = this.playData.clone();
|
||||
result.generatedBy = this.generatedBy;
|
||||
|
||||
return result;
|
||||
@@ -130,7 +131,7 @@ enum abstract SongTimeFormat(String) from String to String
|
||||
var MILLISECONDS = 'ms';
|
||||
}
|
||||
|
||||
class SongTimeChange
|
||||
class SongTimeChange implements ICloneable<SongTimeChange>
|
||||
{
|
||||
public static final DEFAULT_SONGTIMECHANGE:SongTimeChange = new SongTimeChange(0, 100);
|
||||
|
||||
@@ -151,7 +152,7 @@ class SongTimeChange
|
||||
*/
|
||||
@:optional
|
||||
@:alias("b")
|
||||
public var beatTime:Null<Float>;
|
||||
public var beatTime:Float;
|
||||
|
||||
/**
|
||||
* Quarter notes per minute (float). Cannot be empty in the first element of the list,
|
||||
@@ -197,6 +198,11 @@ class SongTimeChange
|
||||
this.beatTuplets = beatTuplets == null ? DEFAULT_BEAT_TUPLETS : beatTuplets;
|
||||
}
|
||||
|
||||
public function clone():SongTimeChange
|
||||
{
|
||||
return new SongTimeChange(this.timeStamp, this.bpm, this.timeSignatureNum, this.timeSignatureDen, this.beatTime, this.beatTuplets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
@@ -211,7 +217,7 @@ class SongTimeChange
|
||||
* These are intended to correct for issues with the chart, or with the song's audio (for example a 10ms delay before the song starts).
|
||||
* This is independent of the offsets applied in the user's settings, which are applied after these offsets and intended to correct for the user's hardware.
|
||||
*/
|
||||
class SongOffsets
|
||||
class SongOffsets implements ICloneable<SongOffsets>
|
||||
{
|
||||
/**
|
||||
* The offset, in milliseconds, to apply to the song's instrumental relative to the chart.
|
||||
@@ -281,6 +287,15 @@ class SongOffsets
|
||||
return value;
|
||||
}
|
||||
|
||||
public function clone():SongOffsets
|
||||
{
|
||||
var result:SongOffsets = new SongOffsets(this.instrumental);
|
||||
result.altInstrumentals = this.altInstrumentals.clone();
|
||||
result.vocals = this.vocals.clone();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
@@ -294,7 +309,7 @@ class SongOffsets
|
||||
* Metadata for a song only used for the music.
|
||||
* For example, the menu music.
|
||||
*/
|
||||
class SongMusicData
|
||||
class SongMusicData implements ICloneable<SongMusicData>
|
||||
{
|
||||
/**
|
||||
* A semantic versioning string for the song data format.
|
||||
@@ -348,13 +363,13 @@ class SongMusicData
|
||||
this.variation = variation == null ? Constants.DEFAULT_VARIATION : variation;
|
||||
}
|
||||
|
||||
public function clone(?newVariation:String = null):SongMusicData
|
||||
public function clone():SongMusicData
|
||||
{
|
||||
var result:SongMusicData = new SongMusicData(this.songName, this.artist, newVariation == null ? this.variation : newVariation);
|
||||
var result:SongMusicData = new SongMusicData(this.songName, this.artist, this.variation);
|
||||
result.version = this.version;
|
||||
result.timeFormat = this.timeFormat;
|
||||
result.divisions = this.divisions;
|
||||
result.timeChanges = this.timeChanges;
|
||||
result.timeChanges = this.timeChanges.clone();
|
||||
result.looped = this.looped;
|
||||
result.generatedBy = this.generatedBy;
|
||||
|
||||
@@ -370,7 +385,7 @@ class SongMusicData
|
||||
}
|
||||
}
|
||||
|
||||
class SongPlayData
|
||||
class SongPlayData implements ICloneable<SongPlayData>
|
||||
{
|
||||
/**
|
||||
* The variations this song has. The associated metadata files should exist.
|
||||
@@ -419,6 +434,20 @@ class SongPlayData
|
||||
ratings = new Map<String, Int>();
|
||||
}
|
||||
|
||||
public function clone():SongPlayData
|
||||
{
|
||||
var result:SongPlayData = new SongPlayData();
|
||||
result.songVariations = this.songVariations.clone();
|
||||
result.difficulties = this.difficulties.clone();
|
||||
result.characters = this.characters.clone();
|
||||
result.stage = this.stage;
|
||||
result.noteStyle = this.noteStyle;
|
||||
result.ratings = this.ratings.clone();
|
||||
result.album = this.album;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
@@ -432,7 +461,7 @@ class SongPlayData
|
||||
* Information about the characters used in this variation of the song.
|
||||
* Create a new variation if you want to change the characters.
|
||||
*/
|
||||
class SongCharacterData
|
||||
class SongCharacterData implements ICloneable<SongCharacterData>
|
||||
{
|
||||
@:optional
|
||||
@:default('')
|
||||
@@ -462,6 +491,14 @@ class SongCharacterData
|
||||
this.instrumental = instrumental;
|
||||
}
|
||||
|
||||
public function clone():SongCharacterData
|
||||
{
|
||||
var result:SongCharacterData = new SongCharacterData(this.player, this.girlfriend, this.opponent, this.instrumental);
|
||||
result.altInstrumentals = this.altInstrumentals.clone();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
@@ -471,7 +508,7 @@ class SongCharacterData
|
||||
}
|
||||
}
|
||||
|
||||
class SongChartData
|
||||
class SongChartData implements ICloneable<SongChartData>
|
||||
{
|
||||
@:default(funkin.data.song.SongRegistry.SONG_CHART_DATA_VERSION)
|
||||
@:jcustomparse(funkin.data.DataParse.semverVersion)
|
||||
@@ -541,6 +578,24 @@ class SongChartData
|
||||
return writer.write(this, pretty ? ' ' : null);
|
||||
}
|
||||
|
||||
public function clone():SongChartData
|
||||
{
|
||||
// We have to manually perform the deep clone here because Map.deepClone() doesn't work.
|
||||
var noteDataClone:Map<String, Array<SongNoteData>> = new Map<String, Array<SongNoteData>>();
|
||||
for (key in this.notes.keys())
|
||||
{
|
||||
noteDataClone.set(key, this.notes.get(key).deepClone());
|
||||
}
|
||||
var eventDataClone:Array<SongEventData> = this.events.deepClone();
|
||||
|
||||
var result:SongChartData = new SongChartData(this.scrollSpeed.clone(), eventDataClone, noteDataClone);
|
||||
result.version = this.version;
|
||||
result.generatedBy = this.generatedBy;
|
||||
result.variation = this.variation;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces a string representation suitable for debugging.
|
||||
*/
|
||||
@@ -550,7 +605,7 @@ class SongChartData
|
||||
}
|
||||
}
|
||||
|
||||
class SongEventDataRaw
|
||||
class SongEventDataRaw implements ICloneable<SongEventDataRaw>
|
||||
{
|
||||
/**
|
||||
* The timestamp of the event. The timestamp is in the format of the song's time format.
|
||||
@@ -604,14 +659,19 @@ class SongEventDataRaw
|
||||
{
|
||||
if (_stepTime != null && !force) return _stepTime;
|
||||
|
||||
return _stepTime = Conductor.getTimeInSteps(this.time);
|
||||
return _stepTime = Conductor.instance.getTimeInSteps(this.time);
|
||||
}
|
||||
|
||||
public function clone():SongEventDataRaw
|
||||
{
|
||||
return new SongEventDataRaw(this.time, this.event, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap SongEventData in an abstract so we can overload operators.
|
||||
*/
|
||||
@:forward(time, event, value, activated, getStepTime)
|
||||
@:forward(time, event, value, activated, getStepTime, clone)
|
||||
abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataRaw
|
||||
{
|
||||
public function new(time:Float, event:String, value:Dynamic = null)
|
||||
@@ -691,11 +751,6 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
|
||||
return this.value == null ? null : cast Reflect.field(this.value, key);
|
||||
}
|
||||
|
||||
public function clone():SongEventData
|
||||
{
|
||||
return new SongEventData(this.time, this.event, this.value);
|
||||
}
|
||||
|
||||
@:op(A == B)
|
||||
public function op_equals(other:SongEventData):Bool
|
||||
{
|
||||
@@ -741,7 +796,7 @@ abstract SongEventData(SongEventDataRaw) from SongEventDataRaw to SongEventDataR
|
||||
}
|
||||
}
|
||||
|
||||
class SongNoteDataRaw
|
||||
class SongNoteDataRaw implements ICloneable<SongNoteDataRaw>
|
||||
{
|
||||
/**
|
||||
* The timestamp of the note. The timestamp is in the format of the song's time format.
|
||||
@@ -825,7 +880,7 @@ class SongNoteDataRaw
|
||||
{
|
||||
if (_stepTime != null && !force) return _stepTime;
|
||||
|
||||
return _stepTime = Conductor.getTimeInSteps(this.time);
|
||||
return _stepTime = Conductor.instance.getTimeInSteps(this.time);
|
||||
}
|
||||
|
||||
@:jignored
|
||||
@@ -841,7 +896,7 @@ class SongNoteDataRaw
|
||||
|
||||
if (_stepLength != null && !force) return _stepLength;
|
||||
|
||||
return _stepLength = Conductor.getTimeInSteps(this.time + this.length) - getStepTime();
|
||||
return _stepLength = Conductor.instance.getTimeInSteps(this.time + this.length) - getStepTime();
|
||||
}
|
||||
|
||||
public function setStepLength(value:Float):Void
|
||||
@@ -852,11 +907,16 @@ class SongNoteDataRaw
|
||||
}
|
||||
else
|
||||
{
|
||||
var lengthMs:Float = Conductor.getStepTimeInMs(value) - this.time;
|
||||
var lengthMs:Float = Conductor.instance.getStepTimeInMs(value) - this.time;
|
||||
this.length = lengthMs;
|
||||
}
|
||||
_stepLength = null;
|
||||
}
|
||||
|
||||
public function clone():SongNoteDataRaw
|
||||
{
|
||||
return new SongNoteDataRaw(this.time, this.data, this.length, this.kind);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user