添加对 Core 的直接引用

This commit is contained in:
OLDREDSTONE
2025-03-25 15:49:57 +08:00
parent 24907abedb
commit 06c19bf10a
296 changed files with 24961 additions and 2 deletions
+269
View File
@@ -0,0 +1,269 @@
using RhythmBase.Adofai.Utils;
using RhythmBase.Exceptions;
using System.Diagnostics.CodeAnalysis;
namespace RhythmBase.Adofai.Components
{
/// <summary>
/// Represents a beat in the ADLevel.
/// </summary>
public struct ADBeat : IComparable<ADBeat>, IEquatable<ADBeat>
{
internal readonly ADLevel? baseLevel => _calculator?.Collection;
/// <summary>
/// Gets or sets the beat only value.
/// </summary>
public readonly float BeatOnly
{
get => _beat + 1f;
set
{
}
}
/// <summary>
/// Gets or sets the time span.
/// </summary>
public readonly TimeSpan TimeSpan
{
get => _timeSpan;
set
{
}
}
/// <summary>
/// Initializes a new instance of the <see cref="ADBeat"/> struct with a specified beat.
/// </summary>
/// <param name="beat">The beat value.</param>
public ADBeat(float beat)
{
this = default;
_beat = beat;
_isBeatLoaded = true;
}
/// <summary>
/// Initializes a new instance of the <see cref="ADBeat"/> struct with a specified time span.
/// </summary>
/// <param name="timeSpan">The time span value.</param>
public ADBeat(TimeSpan timeSpan)
{
this = default;
_timeSpan = timeSpan;
_isTimeSpanLoaded = true;
}
/// <summary>
/// Initializes a new instance of the <see cref="ADBeat"/> struct with a specified calculator and beat.
/// </summary>
/// <param name="calculator">The beat calculator.</param>
/// <param name="beat">The beat value.</param>
public ADBeat(ADBeatCalculator calculator, float beat)
{
this = default;
_calculator = calculator;
_beat = beat;
_isBeatLoaded = true;
}
/// <summary>
/// Initializes a new instance of the <see cref="ADBeat"/> struct with a specified calculator and time span.
/// </summary>
/// <param name="calculator">The beat calculator.</param>
/// <param name="timeSpan">The time span value.</param>
/// <exception cref="OverflowException">Thrown when the time span is less than zero.</exception>
public ADBeat(ADBeatCalculator calculator, TimeSpan timeSpan)
{
this = default;
if (timeSpan < TimeSpan.Zero)
{
throw new OverflowException(string.Format("The time must not be less than zero, but {0} is given", timeSpan));
}
_calculator = calculator;
_timeSpan = timeSpan;
_isTimeSpanLoaded = true;
}
/// <summary>
/// Construct a beat of the 1st beat from the calculator
/// </summary>
/// <param name="calculator">Specified calculator.</param>
/// <returns>The first beat tied to the level.</returns>
public static ADBeat Default(ADBeatCalculator calculator)
{
ADBeat Default = new(calculator, 1f);
return Default;
}
/// <summary>
/// Determine if two beats come from the same level
/// </summary>
/// <param name="a">A beat.</param>
/// <param name="b">Another beat.</param>
/// <param name="throw">If true, an exception will be thrown when two beats do not come from the same level.</param>
/// <returns></returns>
public static bool FromSameLevel(ADBeat a, ADBeat b, bool @throw = false)
{
bool flag = a.baseLevel.Equals(b.baseLevel);
bool FromSameLevel;
if (flag)
{
FromSameLevel = true;
}
else
{
if (@throw)
{
throw new RhythmBaseException("Beats must come from the same ADLevel.");
}
FromSameLevel = false;
}
return FromSameLevel;
}
/// <summary>
/// Determine if two beats are from the same level.
/// <br />
/// If any of them does not come from any level, it will also return true.
/// </summary>
/// <param name="a">A beat.</param>
/// <param name="b">Another beat.</param>
/// <param name="throw">If true, an exception will be thrown when two beats do not come from the same level.</param>
/// <returns></returns>
public static bool FromSameLevelOrNull(ADBeat a, ADBeat b, bool @throw = false) => a.baseLevel == null || b.baseLevel == null || FromSameLevel(a, b, @throw);
public readonly bool FromSameLevel(ADBeat b, bool @throw = false) => FromSameLevel(this, b, @throw);
/// <summary>
/// Determine if two beats are from the same level.
/// <br />
/// If any of them does not come from any level, it will also return true.
/// </summary>
/// <param name="b">Another beat.</param>
/// <param name="throw">If true, an exception will be thrown when two beats do not come from the same level.</param>
/// <returns></returns>
public readonly bool FromSameLevelOrNull(ADBeat b, bool @throw = false) => baseLevel == null || b.baseLevel == null || FromSameLevel(b, @throw);
/// <summary>
/// Returns a new instance of unbinding the level.
/// </summary>
/// <returns>A new instance of unbinding the level.</returns>
public readonly ADBeat WithoutBinding()
{
ADBeat result = this;
result._calculator = null;
return result;
}
private readonly void IfNullThrowException()
{
if (IsEmpty)
{
throw new InvalidRDBeatException();
}
}
/// <summary>
/// Refresh the cache.
/// </summary>
public void ResetCache()
{
float i = BeatOnly;
_isTimeSpanLoaded = false;
}
internal void ResetBPM()
{
_isBeatLoaded = true;
_isTimeSpanLoaded = false;
_isBpmLoaded = false;
}
internal void ResetCPB() => _isBeatLoaded = true;
/// <summary>
/// Gets a value indicating whether this instance is empty.
/// </summary>
/// <value>
/// <c>true</c> if this instance is empty; otherwise, <c>false</c>.
/// </value>
public readonly bool IsEmpty
{
get
{
return _calculator == null || (!_isBeatLoaded && !_isTimeSpanLoaded);
}
}
/// <inheritdoc/>
public static ADBeat operator +(ADBeat a, float b)
{
ADBeat result = new(a._calculator, a.BeatOnly + b);
return result;
}
/// <inheritdoc/>
public static ADBeat operator +(ADBeat a, TimeSpan b)
{
ADBeat result = new(a._calculator, a.TimeSpan + b);
return result;
}
/// <inheritdoc/>
public static ADBeat operator -(ADBeat a, float b)
{
ADBeat result = new(a._calculator, a.BeatOnly - b);
return result;
}
/// <inheritdoc/>
public static ADBeat operator -(ADBeat a, TimeSpan b)
{
ADBeat result = new(a._calculator, a.TimeSpan - b);
return result;
}
/// <inheritdoc/>
public static bool operator >(ADBeat a, ADBeat b) => FromSameLevel(a, b, true) && a.BeatOnly > b.BeatOnly;
/// <inheritdoc/>
public static bool operator <(ADBeat a, ADBeat b) => FromSameLevel(a, b, true) && a.BeatOnly < b.BeatOnly;
/// <inheritdoc/>
public static bool operator >=(ADBeat a, ADBeat b) => FromSameLevel(a, b, true) && a.BeatOnly >= b.BeatOnly;
/// <inheritdoc/>
public static bool operator <=(ADBeat a, ADBeat b) => FromSameLevel(a, b, true) && a.BeatOnly <= b.BeatOnly;
/// <inheritdoc/>
public static bool operator ==(ADBeat a, ADBeat b) => (FromSameLevel(a, b, true) && a._beat == b._beat) || (a._isTimeSpanLoaded && b._isTimeSpanLoaded && a._timeSpan == b._timeSpan) || a.BeatOnly == b.BeatOnly;
/// <inheritdoc/>
public static bool operator !=(ADBeat a, ADBeat b) => !(a == b);
/// <inheritdoc/>
public readonly int CompareTo(ADBeat other) => checked((int)Math.Round((double)unchecked(_beat - other._beat)));
/// <inheritdoc/>
public override readonly string ToString() => string.Format("[{0}]", BeatOnly);
/// <inheritdoc/>
public override readonly bool Equals([NotNull] object obj) => obj.GetType() == typeof(ADBeat) && Equals((obj != null) ? ((ADBeat)obj) : default);
/// <inheritdoc/>
public readonly bool Equals(ADBeat other) => this == other;
/// <inheritdoc/>
public override readonly int GetHashCode() => HashCode.Combine(BeatOnly, baseLevel);
internal ADBeatCalculator? _calculator;
private bool _isBeatLoaded;
private bool _isTimeSpanLoaded;
private bool _isBpmLoaded;
private float _beat;
private TimeSpan _timeSpan;
private float _bpm;
}
}
@@ -0,0 +1,97 @@
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using RhythmBase.Adofai.Converters;
using RhythmBase.Adofai.Events;
using RhythmBase.Adofai.Utils;
using RhythmBase.Exceptions;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Components
{
/// <summary>
/// Adofal level.
/// </summary>
public class ADLevel : ADTileCollection
{
/// <summary>
/// Level settings.
/// </summary>
public ADSettings Settings { get; set; }
/// <summary>
/// Level decoration collection.
/// </summary>
public List<ADBaseEvent> Decorations { get; set; }
/// <summary>
/// Level file path.
/// </summary>
[JsonIgnore]
public string Path => _path;
/// <summary>
/// Level directory path.
/// </summary>
[JsonIgnore]
public string Directory => System.IO.Path.GetDirectoryName(_path);
/// <summary>
/// Get all the events of the level.
/// </summary>
public override IEnumerable<ADBaseEvent> Events
{
get
{
foreach (ADBaseEvent tile in base.Events)
yield return tile;
foreach (ADBaseEvent tile2 in Decorations)
yield return tile2;
}
}
/// <summary>
/// The calculator that comes with the level.
/// </summary>
[JsonIgnore]
public ADBeatCalculator Calculator { get; }
public ADLevel()
{
Settings = new ADSettings();
Decorations = [];
Calculator = new ADBeatCalculator(this);
}
public ADLevel(IEnumerable<ADTile> items)
{
Settings = new ADSettings();
Decorations = [];
Calculator = new ADBeatCalculator(this);
foreach (ADTile tile in items)
Add(tile);
}
/// <summary>
/// The default level within the game.
/// </summary>
public static ADLevel Default => [];
/// <summary>
/// Read from file as level.
/// Use default input settings.
/// Supports .rdlevel, .rdzip, .zip file extension.
/// </summary>
/// <param name="filepath">File path.</param>
/// <returns>An instance of a level that reads from a file.</returns>
public static ADLevel Read(string filepath) => Read(filepath, new LevelReadOrWriteSettings());
/// <summary>
/// Read from file as level.
/// Supports .rdlevel, .rdzip, .zip file extension.
/// </summary>
/// <param name="filepath">File path.</param>
/// <param name="settings">Input settings.</param>
/// <returns>An instance of a level that reads from a file.</returns>
public static ADLevel Read(string filepath, LevelReadOrWriteSettings settings)
{
JsonSerializer LevelSerializer = new();
LevelSerializer.Converters.Add(new ADLevelConverter(filepath, settings));
string extension = System.IO.Path.GetExtension(filepath);
if (extension != ".adofai")
{
throw new RhythmBaseException("File not supported.");
}
return LevelSerializer.Deserialize<ADLevel>(new JsonTextReader(File.OpenText(filepath)))!;
}
internal string _path;
}
}
@@ -0,0 +1,145 @@
using System;
using System.Collections.Generic;
using RhythmBase.Adofai.Events;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
namespace RhythmBase.Adofai.Components
{
public class ADSettings
{
public ADSettings()
{
RequiredMods = [];
}
public int Version { get; set; }
public string Artist { get; set; }
public SpecialArtistTypes SpecialArtistType { get; set; }
public string ArtistPermission { get; set; }
public string Song { get; set; }
public string Author { get; set; }
public bool SeparateCountdownTime { get; set; }
public string PreviewImage { get; set; }
public string PreviewIcon { get; set; }
public RDColor PreviewIconColor { get; set; }
public float PreviewSongStart { get; set; }
public float PreviewSongDuration { get; set; }
public bool SeizureWarning { get; set; }
public string LevelDesc { get; set; }
public string LevelTags { get; set; }
public string ArtistLinks { get; set; }
public int Difficulty { get; set; }
public List<string> RequiredMods { get; set; }
public string SongFilename { get; set; }
public float Bpm { get; set; }
public float Volume { get; set; }
public float Offset { get; set; }
public float Pitch { get; set; }
public string Hitsound { get; set; }
public float HitsoundVolume { get; set; }
public float CountdownTicks { get; set; }
public ADTrackColorTypes TrackColorType { get; set; }
public RDColor TrackColor { get; set; }
public RDColor SecondaryTrackColor { get; set; }
public float TrackColorAnimDuration { get; set; }
public ADTrackColorPulses TrackColorPulse { get; set; }
public float TrackPulseLength { get; set; }
public ADTrackStyles TrackStyle { get; set; }
public ADTrackAnimationTypes TrackAnimation { get; set; }
public int BeatsAhead { get; set; }
public ADTrackDisappearAnimationTypes TrackDisappearAnimation { get; set; }
public int BeatsBehind { get; set; }
public RDColor BackgroundColor { get; set; }
public bool ShowDefaultBGIfNoImage { get; set; }
public string BgImage { get; set; }
public RDColor BgImageColor { get; set; }
public RDPointI Parallax { get; set; }
public BgDisplayModes BgDisplayMode { get; set; }
public bool LockRot { get; set; }
public bool LoopBG { get; set; }
public float ScalingRatio { get; set; }
public ADCameraRelativeTo RelativeTo { get; set; }
public RDPointI Position { get; set; }
public float Rotation { get; set; }
public float Zoom { get; set; }
public string BgVideo { get; set; }
public bool LoopVideo { get; set; }
public int VidOffset { get; set; }
public bool FloorIconOutlines { get; set; }
public bool StickToFloors { get; set; }
public EaseType PlanetEase { get; set; }
public int PlanetEaseParts { get; set; }
public ADEasePartBehaviors PlanetEasePartBehavior { get; set; }
public RDColor DefaultTextColor { get; set; }
public RDColor DefaultTextShadowColor { get; set; }
public string CongratsText { get; set; }
public string PerfectText { get; set; }
public bool LegacyFlash { get; set; }
public bool LegacyCamRelativeTo { get; set; }
public bool LegacySpriteTiles { get; set; }
}
}
@@ -0,0 +1,43 @@
using RhythmBase.Adofai.Events;
using System.Collections;
namespace RhythmBase.Adofai.Components
{
public abstract class ADTileCollection : ICollection<ADTile>
{
protected ADTileCollection()
{
tileOrder = [];
IsReadOnly = false;
EndTile = [];
}
public int Count => tileOrder.Count;
public bool IsReadOnly { get; }
public ADTile EndTile { get; }
public ADTile this[int index] => index == tileOrder.Count ? EndTile : tileOrder[index];
public virtual IEnumerable<ADBaseEvent> Events
{
get
{
foreach (ADTile tile in tileOrder)
foreach (ADBaseTileEvent action in tile)
yield return action;
foreach (ADBaseTileEvent action2 in EndTile)
yield return action2;
}
}
public void Add(ADTile item) => tileOrder.Add(item);
public void Clear() => tileOrder.Clear();
public void CopyTo(ADTile[] array, int arrayIndex) => tileOrder.CopyTo(array, arrayIndex);
public bool Contains(ADTile item) => tileOrder.Contains(item);
public bool Remove(ADTile item) => tileOrder.Remove(item);
public IEnumerator<ADTile> GetEnumerator() => tileOrder.GetEnumerator();
/// <summary>
/// Get the index of tile.
/// </summary>
/// <param name="item">The index of tile.</param>
/// <returns></returns>
public int IndexOf(ADTile item) => item == EndTile ? Count : tileOrder.IndexOf(item);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
internal List<ADTile> tileOrder;
}
}
@@ -0,0 +1,16 @@
using System;
namespace RhythmBase.Adofai.Components
{
public enum ADTrackAnimationTypes
{
None,
Assemble,
Assemble_Far,
Extend,
Grow,
Grow_Spin,
Fade,
Drop,
Rise
}
}
@@ -0,0 +1,14 @@
using System;
namespace RhythmBase.Adofai.Components
{
public enum ADTrackDisappearAnimationTypes
{
None,
Scatter,
Scatter_Far,
Retract,
Shrink,
Shrink_Spin,
Fade
}
}
@@ -0,0 +1,28 @@
using RhythmBase.Adofai.Events;
using System.Collections;
namespace RhythmBase.Adofai.Components
{
public class ADTypedList<TEvent> : IEnumerable<TEvent> where TEvent : ADBaseEvent
{
public ADTypedList()
{
list = [];
_types = [];
}
public void Add(TEvent item)
{
list.Add(item);
_types.Add(item.Type);
}
public object Remove(TEvent item)
{
_types.Remove(item.Type);
return list.Remove(item);
}
public override string ToString() => string.Format("Count = {0}", list.Count);
public IEnumerator<TEvent> GetEnumerator() => list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => list.GetEnumerator();
private readonly List<TEvent> list;
protected internal HashSet<ADEventType> _types;
}
}
@@ -0,0 +1,10 @@
using System;
namespace RhythmBase.Adofai.Components
{
public enum BgDisplayModes
{
FitToScreen,
Unscaled,
Tiled
}
}
@@ -0,0 +1,60 @@
using System;
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Adofai.Utils;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Converters
{
internal class ADBaseEventConverter<TEvent>(ADLevel level, LevelReadOrWriteSettings inputSettings) : JsonConverter<TEvent> where TEvent : ADBaseEvent
{
public override bool CanRead
{
get
{
return _canread;
}
}
public override bool CanWrite
{
get
{
return _canwrite;
}
}
public override void WriteJson(JsonWriter writer, TEvent? value, JsonSerializer serializer) => throw new NotImplementedException();
public override TEvent ReadJson(JsonReader reader, Type objectType, TEvent? existingValue, bool hasExistingValue, JsonSerializer serializer) => GetDeserializedObject((JObject)JToken.ReadFrom(reader), objectType, existingValue, hasExistingValue, serializer);
public virtual TEvent GetDeserializedObject(JObject jobj, Type objectType, TEvent existingValue, bool hasExistingValue, JsonSerializer serializer)
{
Type SubClassType = Utils.Utils.ADConvertToType(jobj["eventType"].ToObject<string>());
_canread = false;
existingValue = Conversions.ToGenericParameter<TEvent>((SubClassType != null) ? jobj.ToObject(SubClassType, serializer) : jobj.ToObject<ADCustomEvent>(serializer));
_canread = true;
return existingValue;
}
public virtual JObject SetSerializedObject(TEvent value, JsonSerializer serializer)
{
_canwrite = false;
JObject JObj = JObject.FromObject(value, serializer);
_canwrite = true;
JObj.Remove("type");
JToken s = JObj.First;
s.AddBeforeSelf(new JProperty("eventType", value.Type.ToString()));
return JObj;
}
protected readonly ADLevel level = level;
protected readonly LevelReadOrWriteSettings settings = inputSettings;
protected bool _canread = true;
protected bool _canwrite = true;
}
}
@@ -0,0 +1,42 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Adofai.Utils;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Converters
{
internal class ADBaseTileEventConverter<TEvent>(ADLevel level, LevelReadOrWriteSettings inputSettings) : ADBaseEventConverter<TEvent>(level, inputSettings) where TEvent : ADBaseTileEvent
{
public override TEvent GetDeserializedObject(JObject jobj, Type objectType, TEvent existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken jtoken = jobj["floor"];
int? parentIndex = (jtoken != null) ? new int?(jtoken.ToObject<int>()) : null;
_canread = false;
if (Utils.Utils.ADConvertToType(jobj["eventType"].ToObject<string>()) == typeof(ADCustomEvent))
{
existingValue = (TEvent)(object)new ADCustomTileEventConverter(level, settings).GetDeserializedObject(jobj, objectType, null, hasExistingValue, serializer);
}
else
{
jobj.Remove("floor");
existingValue = base.GetDeserializedObject(jobj, objectType, existingValue, hasExistingValue, serializer);
}
_canread = true;
if (parentIndex != null)
{
existingValue.Parent = level[parentIndex.Value];
existingValue.Parent.Add((ADBaseTileEvent)(object)existingValue);
}
return existingValue;
}
public override JObject SetSerializedObject(TEvent value, JsonSerializer serializer)
{
JObject jobj = base.SetSerializedObject(value, serializer);
JToken s = jobj.First;
s.AddBeforeSelf(new JProperty("floor", level.tileOrder.IndexOf(value.Parent)));
return jobj;
}
}
}
@@ -0,0 +1,16 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Converters
{
internal class ADCustomEventConverter(ADLevel level, LevelReadOrWriteSettings settings) : ADBaseEventConverter<ADCustomEvent>(level, settings)
{
public override ADCustomEvent GetDeserializedObject(JObject jobj, Type objectType, ADCustomEvent existingValue, bool hasExistingValue, JsonSerializer serializer) => new()
{
Data = jobj
};
}
}
@@ -0,0 +1,17 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Converters
{
internal class ADCustomTileEventConverter(ADLevel level, LevelReadOrWriteSettings settings) : ADBaseTileEventConverter<ADCustomTileEvent>(level, settings)
{
public override ADCustomTileEvent GetDeserializedObject(JObject jobj, Type objectType, ADCustomTileEvent existingValue, bool hasExistingValue, JsonSerializer serializer) => new()
{
Parent = level[jobj["floor"].ToObject<int>()],
Data = jobj
};
}
}
@@ -0,0 +1,87 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Adofai.Utils;
using RhythmBase.Extensions;
using RhythmBase.Converters;
using RhythmBase.Settings;
namespace RhythmBase.Adofai.Converters
{
internal class ADLevelConverter(string location, LevelReadOrWriteSettings settings) : JsonConverter<ADLevel>
{
public override void WriteJson(JsonWriter writer, ADLevel? value, JsonSerializer serializer)
{
JsonSerializerSettings AllInOneSerializer = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.None
};
IList<JsonConverter> converters = AllInOneSerializer.Converters;
converters.Add(new StringEnumConverter());
converters.Add(new ColorConverter());
writer.Formatting = settings.Indented ? Formatting.Indented : Formatting.None;
writer.WriteStartObject();
writer.WritePropertyName("angleData");
writer.WriteStartArray();
foreach (ADTile item in value!)
writer.WriteRawValue(JsonConvert.SerializeObject(item.Angle, Formatting.None));
writer.WriteEndArray();
writer.WritePropertyName("settings");
writer.WriteRawValue(JsonConvert.SerializeObject(value.Settings, Formatting.Indented, AllInOneSerializer));
writer.WritePropertyName("actions");
writer.WriteStartArray();
foreach (ADTile item2 in value)
writer.WriteRawValue(JsonConvert.SerializeObject(item2, Formatting.None, AllInOneSerializer));
writer.WriteEndArray();
writer.WritePropertyName("decorations");
writer.WriteStartArray();
foreach (ADBaseEvent item3 in value.Decorations)
writer.WriteRawValue(JsonConvert.SerializeObject(item3, Formatting.None, AllInOneSerializer));
writer.WriteEndArray();
writer.WriteEndObject();
writer.Close();
}
public override ADLevel ReadJson(JsonReader reader, Type objectType, ADLevel? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
ADLevel outLevel = new()
{
_path = fileLocation
};
JsonSerializer AllInOneSerializer = outLevel.GetSerializer(settings);
JArray JActions = [];
JArray JDecorations = [];
while (reader.Read())
{
string name = (string)reader.Value!;
reader.Read();
object left = name;
switch (name)
{
case "settings":
JObject jobj = JObject.Load(reader);
outLevel.Settings = jobj.ToObject<ADSettings>(AllInOneSerializer)!;
break;
case "angleData":
JArray jobj2 = JArray.Load(reader);
//outLevel.AddRange(jobj2.ToObject<List<ADTile>>(AllInOneSerializer)!);
break;
case "actions":
JActions = JArray.Load(reader);
break;
case "decorations":
JDecorations = JArray.Load(reader);
break;
}
}
reader.Close();
JActions.ToObject<List<ADBaseTileEvent>>(AllInOneSerializer);
outLevel.Decorations.AddRange(JDecorations.ToObject<List<ADBaseEvent>>(AllInOneSerializer)!);
return outLevel;
}
private readonly string fileLocation = location;
private readonly LevelReadOrWriteSettings settings = settings;
}
}
@@ -0,0 +1,20 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
namespace RhythmBase.Adofai.Converters
{
internal class ADTileConverter(ADLevel level) : JsonConverter<ADTile>
{
public override void WriteJson(JsonWriter writer, ADTile value, JsonSerializer serializer) => throw new NotImplementedException();
public override ADTile ReadJson(JsonReader reader, Type objectType, ADTile existingValue, bool hasExistingValue, JsonSerializer serializer) => new()
{
Angle = JToken.Load(reader).ToObject<float>(),
Parent = level
};
private readonly ADLevel level = level;
}
}
@@ -0,0 +1,122 @@
using System;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADAddDecoration : ADBaseTileEvent
{
public ADAddDecoration()
{
Type = ADEventType.AddDecoration;
}
public override ADEventType Type { get; }
public string DecorationImage { get; set; }
public RDPointN Position { get; set; }
public ADDecorationRelativeTo RelativeTo { get; set; }
public RDSizeN PivotOffset { get; set; }
public float Rotation { get; set; }
public bool LockRotation { get; set; }
public RDSizeN Scale { get; set; }
public bool LockScale { get; set; }
public RDSizeN Tile { get; set; }
public RDColor Color { get; set; }
public float Opacity { get; set; }
public int Depth { get; set; }
public RDSizeN Parallax { get; set; }
public RDSizeN ParallaxOffset { get; set; }
public string Tag { get; set; }
public bool ImageSmoothing { get; set; }
public BlendModes BlendMode { get; set; }
public MaskingTypes MaskingType { get; set; }
public bool UseMaskingDepth { get; set; }
public int MaskingFrontDepth { get; set; }
public int MaskingBackDepth { get; set; }
public HitboxTypes Hitbox { get; set; }
public string HitboxEventTag { get; set; }
public FailHitboxTypes FailHitboxType { get; set; }
public RDSizeN FailHitboxScale { get; set; }
public RDSizeN FailHitboxOffset { get; set; }
public int FailHitboxRotation { get; set; }
public string Components { get; set; }
public enum BlendModes
{
None,
Darken,
Multiply,
ColorBurn,
LinearBurn,
DarkerColor,
Lighten,
Screen,
ColorDodge,
LinearDodge,
LighterColor,
Overlay,
SoftLight,
HardLight,
VividLight,
LinearLight,
PinLight,
HardMix,
Difference,
Exclusion,
Subtract,
Divide,
Hue,
Saturation,
Color,
Luminosity
}
public enum MaskingTypes
{
None,
Mask,
VisibleInsideMask,
VisibleOutsideMask
}
public enum HitboxTypes
{
None,
Kill,
Event
}
public enum FailHitboxTypes
{
Box,
Circle,
Capsule
}
}
}
@@ -0,0 +1,95 @@
using System;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADAddObject : ADBaseEvent
{
public ADAddObject()
{
Type = ADEventType.AddObject;
}
public override ADEventType Type { get; }
public ObjectTypes ObjectType { get; set; }
public PlanetColorTypes PlanetColorType { get; set; }
public RDColor PlanetColor { get; set; }
public RDColor PlanetTailColor { get; set; }
public TrackTypes TrackType { get; set; }
public float TrackAngle { get; set; }
public ADTrackColorTypes TrackColorType { get; set; }
public RDColor TrackColor { get; set; }
public RDColor SecondaryTrackColor { get; set; }
public float TrackColorAnimDuration { get; set; }
public float TrackOpacity { get; set; }
public ADTrackStyles TrackStyle { get; set; }
public string TrackIcon { get; set; }
public float TrackIconAngle { get; set; }
public bool TrackRedSwirl { get; set; }
public bool TrackGraySetSpeedIcon { get; set; }
public float TrackSetSpeedIconBpm { get; set; }
public bool TrackGlowEnabled { get; set; }
public RDColor TrackGlowColor { get; set; }
public RDPointN Position { get; set; }
public ADCameraRelativeTo RelativeTo { get; set; }
public RDSizeN PivotOffset { get; set; }
public float Rotation { get; set; }
public bool LockRotation { get; set; }
public RDSizeN Scale { get; set; }
public bool LockScale { get; set; }
public int Depth { get; set; }
public RDSizeN Parallax { get; set; }
public RDSizeN ParallaxOffset { get; set; }
public string Tag { get; set; }
public enum ObjectTypes
{
Floor,
Planet
}
public enum PlanetColorTypes
{
DefaultRed,
planetColorType,
Gold,
Overseer,
Custom
}
public enum TrackTypes
{
Normal,
Midspin
}
}
}
+44
View File
@@ -0,0 +1,44 @@
using System;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADAddText : ADBaseEvent
{
public ADAddText()
{
Type = ADEventType.AddText;
}
public override ADEventType Type { get; }
public string DecText { get; set; }
public string Font { get; set; }
public RDPointN Position { get; set; }
public ADCameraRelativeTo RelativeTo { get; set; }
public RDSizeN PivotOffset { get; set; }
public float Rotation { get; set; }
public bool LockRotation { get; set; }
public RDSizeN Scale { get; set; }
public bool LockScale { get; set; }
public RDColor Color { get; set; }
public float Opacity { get; set; }
public int Depth { get; set; }
public RDSizeN Parallax { get; set; }
public RDSizeN ParallaxOffset { get; set; }
public string Tag { get; set; }
}
}
@@ -0,0 +1,47 @@
using System;
using Newtonsoft.Json;
namespace RhythmBase.Adofai.Events
{
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class ADAnimateTrack : ADBaseTileEvent
{
public ADAnimateTrack()
{
Type = ADEventType.AnimateTrack;
}
public override ADEventType Type { get; }
public TrackAnimations? TrackAnimation { get; set; }
public TrackDisappearAnimations? TrackDisappearAnimation { get; set; }
public int BeatsAhead { get; set; }
public int BeatsBehind { get; set; }
public enum TrackAnimations
{
None,
Assemble,
Assemble_Far,
Extend,
Grow,
Grow_Spin,
Fade,
Drop,
Rise
}
public enum TrackDisappearAnimations
{
None,
Scatter,
Scatter_Far,
Retract,
Shrink,
Shrink_Spin,
Fade
}
}
}
@@ -0,0 +1,19 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADAutoPlayTiles : ADBaseTileEvent
{
public ADAutoPlayTiles()
{
Type = ADEventType.AutoPlayTiles;
}
public override ADEventType Type { get; }
public bool Enabled { get; set; }
public bool ShowStatusText { get; set; }
public bool SafetyTiles { get; set; }
}
}
@@ -0,0 +1,10 @@
using System;
namespace RhythmBase.Adofai.Events
{
public abstract class ADBaseEvent
{
public abstract ADEventType Type { get; }
public override string ToString() => Type.ToString();
}
}
@@ -0,0 +1,10 @@
using System;
namespace RhythmBase.Adofai.Events
{
public abstract class ADBaseTaggedTileAction : ADBaseTileEvent
{
public float AngleOffset { get; set; }
public string EventTag { get; set; }
}
}
@@ -0,0 +1,12 @@
using System;
using Newtonsoft.Json;
namespace RhythmBase.Adofai.Events
{
public abstract class ADBaseTileEvent : ADBaseEvent
{
[JsonIgnore]
public ADTile Parent { get; set; }
public override string ToString() => string.Format("{0}", Type);
}
}
+28
View File
@@ -0,0 +1,28 @@
using System;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADBloom : ADBaseTaggedTileAction, IEaseEvent
{
public ADBloom()
{
Type = ADEventType.Bloom;
}
public override ADEventType Type { get; }
public bool Enabled { get; set; }
public int Threshold { get; set; }
public int Intensity { get; set; }
public RDColor Color { get; set; }
public float Duration { get; set; }
public EaseType Ease { get; set; }
}
}
@@ -0,0 +1,13 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADBookmark : ADBaseTileEvent
{
public ADBookmark()
{
Type = ADEventType.Bookmark;
}
public override ADEventType Type { get; }
}
}
@@ -0,0 +1,12 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADCameraRelativeTo
{
Player,
Tile,
Global,
LastPosition,
LastPositionNoRotation
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADCheckpoint : ADBaseTileEvent
{
public ADCheckpoint()
{
Type = ADEventType.Checkpoint;
}
public override ADEventType Type { get; }
public int TileOffset { get; set; }
}
}
@@ -0,0 +1,34 @@
using RhythmBase.Components;
using System;
namespace RhythmBase.Adofai.Events
{
public class ADColorTrack : ADBaseTileEvent
{
public ADColorTrack()
{
Type = ADEventType.ColorTrack;
}
public override ADEventType Type { get; }
public ADTrackColorTypes TrackColorType { get; set; }
public RDColor TrackColor { get; set; }
public RDColor SecondaryTrackColor { get; set; }
public float TrackColorAnimDuration { get; set; }
public ADTrackColorPulses TrackColorPulse { get; set; }
public float TrackPulseLength { get; set; }
public ADTrackStyles TrackStyle { get; set; }
public string TrackTexture { get; set; }
public float TrackTextureScale { get; set; }
public float TrackGlowIntensity { get; set; }
}
}
@@ -0,0 +1,39 @@
using System;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADCustomBackground : ADBaseTaggedTileAction
{
public ADCustomBackground()
{
Type = ADEventType.CustomBackground;
}
public override ADEventType Type { get; }
public RDColor Color { get; set; }
public string BgImage { get; set; }
public RDColor ImageColor { get; set; }
public RDPoint Parallax { get; set; }
public BgDisplayModes BgDisplayMode { get; set; }
public bool ImageSmoothing { get; set; }
public bool LockRot { get; set; }
public bool LoopBG { get; set; }
public float ScalingRatio { get; set; }
public enum BgDisplayModes
{
FitToScreen,
Unscaled,
Tiled
}
}
}
@@ -0,0 +1,28 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RhythmBase.Adofai.Events
{
public class ADCustomEvent : ADBaseEvent
{
public ADCustomEvent()
{
Type = ADEventType.CustomEvent;
}
public override ADEventType Type { get; }
[JsonIgnore]
public string ActureType
{
get
{
return Data["eventType"].ToString();
}
}
public JObject Data { get; set; }
public override string ToString() => ActureType;
}
}
@@ -0,0 +1,28 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace RhythmBase.Adofai.Events
{
public class ADCustomTileEvent : ADBaseTileEvent
{
public ADCustomTileEvent()
{
Type = ADEventType.CustomTileEvent;
}
public override ADEventType Type { get; }
[JsonIgnore]
public string ActureType
{
get
{
return Data["eventType"].ToString();
}
}
public JObject Data { get; set; }
public override string ToString() => string.Format("{0}({1}): {2}", Parent.Index, Parent.Angle, ActureType);
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADDecorationRelativeTo
{
Tile,
Global,
RedPlanet,
BluePlanet,
GreenPlanet,
Camera,
CameraAspect,
LastPosition
}
}
@@ -0,0 +1,9 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADEasePartBehaviors
{
Repeat,
Mirror
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADEditorComment : ADBaseTileEvent
{
public ADEditorComment()
{
Type = ADEventType.EditorComment;
}
public override ADEventType Type { get; }
public string Comment { get; set; }
}
}
@@ -0,0 +1,52 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADEventType
{
AddDecoration,
AddObject,
AddText,
AnimateTrack,
AutoPlayTiles,
Bloom,
Bookmark,
Checkpoint,
ColorTrack,
CustomBackground,
CustomEvent,
CustomTileEvent,
EditorComment,
Flash,
FreeRoam,
FreeRoamRemove,
FreeRoamTwirl,
HallOfMirrors,
Hide,
Hold,
MoveCamera,
MoveDecorations,
MoveTrack,
MultiPlanet,
Pause,
PlaySound,
PositionTrack,
RecolorTrack,
RepeatEvents,
ScaleMargin,
ScalePlanets,
ScaleRadius,
ScreenScroll,
ScreenTile,
SetConditionalEvents,
SetDefaultText,
SetFilter,
SetHitsound,
SetHoldSound,
SetObject,
SetPlanetRotation,
SetSpeed,
SetText,
ShakeScreen,
Twirl
}
}
+30
View File
@@ -0,0 +1,30 @@
using System;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADFlash : ADBaseTaggedTileAction, IEaseEvent
{
public ADFlash()
{
Type = ADEventType.Flash;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public string Plane { get; set; }
public RDColor StartColor { get; set; }
public float StartOpacity { get; set; }
public RDColor EndColor { get; set; }
public float EndOpacity { get; set; }
public EaseType Ease { get; set; }
}
}
@@ -0,0 +1,26 @@
using System;
using Newtonsoft.Json;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADFreeRoam : ADBaseTileEvent, IEaseEvent
{
public ADFreeRoam()
{
Type = ADEventType.FreeRoam;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public int Size { get; set; }
public int PositionOffset { get; set; }
public int OutTime { get; set; }
[JsonProperty("OutEase")]
public EaseType Ease { get; set; }
public string HitsoundOnBeats { get; set; }
public string HitsoundOffBeats { get; set; }
public int CountdownTicks { get; set; }
public int AngleCorrectionDir { get; set; }
}
}
@@ -0,0 +1,12 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADFreeRoamRemove : ADBaseTileEvent
{
public override ADEventType Type { get; }
public int Position { get; set; }
public int Size { get; set; }
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADFreeRoamTwirl : ADBaseTileEvent
{
public ADFreeRoamTwirl()
{
Type = ADEventType.FreeRoamTwirl;
}
public override ADEventType Type { get; }
public int Position { get; set; }
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADHallOfMirrors : ADBaseTaggedTileAction
{
public ADHallOfMirrors()
{
Type = ADEventType.HallOfMirrors;
}
public override ADEventType Type { get; }
public bool Enabled { get; set; }
}
}
+17
View File
@@ -0,0 +1,17 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADHide : ADBaseTileEvent
{
public ADHide()
{
Type = ADEventType.Hide;
}
public override ADEventType Type { get; }
public bool HideJudgment { get; set; }
public bool HideTileIcon { get; set; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADHold : ADBaseTileEvent
{
public ADHold()
{
Type = ADEventType.Hold;
}
public override ADEventType Type { get; }
public int Duration { get; set; }
public int DistanceMultiplier { get; set; }
public bool LandingAnimation { get; set; }
}
}
@@ -0,0 +1,34 @@
using System;
using Newtonsoft.Json;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class ADMoveCamera : ADBaseTaggedTileAction, IEaseEvent
{
public ADMoveCamera()
{
Type = ADEventType.MoveCamera;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public EaseType Ease { get; set; }
public bool DontDisable { get; set; }
public bool MinVfxOnly { get; set; }
public ADCameraRelativeTo RelativeTo { get; set; }
public RDPoint? Position { get; set; }
public float Rotation { get; set; }
public float Zoom { get; set; }
}
}
@@ -0,0 +1,64 @@
using System;
using Newtonsoft.Json;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class ADMoveDecorations : ADBaseTaggedTileAction, IEaseEvent
{
public ADMoveDecorations()
{
Type = ADEventType.MoveDecorations;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public string Tag { get; set; }
public EaseType Ease { get; set; }
public RDPoint? PositionOffset { get; set; }
public RDPoint? ParallaxOffset { get; set; }
public bool? Visible { get; set; }
public ADDecorationRelativeTo? RelativeTo { get; set; }
public string DecorationImage { get; set; }
public RDSize? PivotOffset { get; set; }
public float? RotationOffset { get; set; }
public RDSize? Scale { get; set; }
public RDColor? Color { get; set; }
public float? Opacity { get; set; }
public int? Depth { get; set; }
public RDPoint? Parallax { get; set; }
public MaskingTypes? MaskingType { get; set; }
public bool? UseMaskingDepth { get; set; }
public int? MaskingFrontDepth { get; set; }
public int? MaskingBackDepth { get; set; }
public enum MaskingTypes
{
None,
Mask,
VisibleInsideMask,
VisibleOutsideMask
}
}
}
@@ -0,0 +1,55 @@
using System;
using System.Runtime.CompilerServices;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADMoveTrack : ADBaseTaggedTileAction, IEaseEvent
{
public ADMoveTrack()
{
Type = ADEventType.MoveTrack;
}
public override ADEventType Type { get; }
public object StartTile
{
[CompilerGenerated]
get
{
return StartTile;
}
[CompilerGenerated]
set
{
StartTile = RuntimeHelpers.GetObjectValue(value);
}
}
public object EndTile
{
[CompilerGenerated]
get
{
return EndTile;
}
[CompilerGenerated]
set
{
EndTile = RuntimeHelpers.GetObjectValue(value);
}
}
public int GapLength { get; set; }
public float Duration { get; set; }
public RDPoint PositionOffset { get; set; }
public EaseType Ease { get; set; }
public bool MaxVfxOnly { get; set; }
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADMultiPlanet : ADBaseTileEvent
{
public ADMultiPlanet()
{
Type = ADEventType.MultiPlanet;
}
public override ADEventType Type { get; }
public string Planets { get; set; }
}
}
+19
View File
@@ -0,0 +1,19 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADPause : ADBaseTileEvent
{
public ADPause()
{
Type = ADEventType.Pause;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public int CountdownTicks { get; set; }
public int AngleCorrectionDir { get; set; }
}
}
@@ -0,0 +1,17 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADPlaySound : ADBaseTaggedTileAction
{
public ADPlaySound()
{
Type = ADEventType.PlaySound;
}
public override ADEventType Type { get; }
public string Hitsound { get; set; }
public int HitsoundVolume { get; set; }
}
}
@@ -0,0 +1,45 @@
using System;
using System.Runtime.CompilerServices;
using Newtonsoft.Json;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADPositionTrack : ADBaseTileEvent
{
public ADPositionTrack()
{
Type = ADEventType.PositionTrack;
}
public override ADEventType Type { get; }
public RDPoint PositionOffset { get; set; }
public object RelativeTo
{
[CompilerGenerated]
get
{
return RelativeTo;
}
[CompilerGenerated]
set
{
RelativeTo = RuntimeHelpers.GetObjectValue(value);
}
}
public float Rotation { get; set; }
public float Scale { get; set; }
public float Opacity { get; set; }
public bool JustThisTile { get; set; }
public bool SditorOnly { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? StickToFloors { get; set; }
}
}
@@ -0,0 +1,67 @@
using System;
using System.Runtime.CompilerServices;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADRecolorTrack : ADBaseTaggedTileAction, IEaseEvent
{
public ADRecolorTrack()
{
Type = ADEventType.RecolorTrack;
}
public override ADEventType Type { get; }
public object StartTile
{
[CompilerGenerated]
get
{
return StartTile;
}
[CompilerGenerated]
set
{
StartTile = RuntimeHelpers.GetObjectValue(value);
}
}
public object EndTile
{
[CompilerGenerated]
get
{
return EndTile;
}
[CompilerGenerated]
set
{
EndTile = RuntimeHelpers.GetObjectValue(value);
}
}
public int GapLength { get; set; }
public float Duration { get; set; }
public ADTrackColorTypes TrackColorType { get; set; }
public RDColor TrackColor { get; set; }
public RDColor SecondaryTrackColor { get; set; }
public float TrackColorAnimDuration { get; set; }
public ADTrackColorPulses TrackColorPulse { get; set; }
public float TrackPulseLength { get; set; }
public ADTrackStyles TrackStyle { get; set; }
public float TrackGlowIntensity { get; set; }
public EaseType Ease { get; set; }
}
}
@@ -0,0 +1,31 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADRepeatEvents : ADBaseTileEvent
{
public ADRepeatEvents()
{
Type = ADEventType.RepeatEvents;
}
public override ADEventType Type { get; }
public RepeatTypes RepeatType { get; set; }
public int Repetitions { get; set; }
public int FloorCount { get; set; }
public float Interval { get; set; }
public bool ExecuteOnCurrentFloor { get; set; }
public string Tag { get; set; }
public enum RepeatTypes
{
Beat,
Floor
}
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADScaleMargin : ADBaseTileEvent
{
public ADScaleMargin()
{
Type = ADEventType.ScaleMargin;
}
public override ADEventType Type { get; }
public int Scale { get; set; }
}
}
@@ -0,0 +1,31 @@
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADScalePlanets : ADBaseTaggedTileAction, IEaseEvent
{
public ADScalePlanets()
{
Type = ADEventType.ScalePlanets;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public TargetPlanets TargetPlanet { get; set; }
[EaseProperty]
public int Scale { get; set; }
public EaseType Ease { get; set; }
public enum TargetPlanets
{
FirePlanet,
IcePlanet,
GreenPlanet,
All
}
}
}
@@ -0,0 +1,15 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADScaleRadius : ADBaseTileEvent
{
public ADScaleRadius()
{
Type = ADEventType.ScaleRadius;
}
public override ADEventType Type { get; }
public int Scale { get; set; }
}
}
@@ -0,0 +1,16 @@
using System;
using RhythmBase.Components;
namespace RhythmBase.Adofai.Events
{
public class ADScreenScroll : ADBaseTaggedTileAction
{
public ADScreenScroll()
{
Type = ADEventType.ScreenScroll;
}
public override ADEventType Type { get; }
public RDSizeN Scroll { get; set; }
}
}
@@ -0,0 +1,22 @@
using System;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADScreenTile : ADBaseTaggedTileAction, IEaseEvent
{
public ADScreenTile()
{
Type = ADEventType.ScreenTile;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public RDPoint Tile { get; set; }
public EaseType Ease { get; set; }
}
}
@@ -0,0 +1,37 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetConditionalEvents : ADBaseTileEvent
{
public ADSetConditionalEvents()
{
Type = ADEventType.SetConditionalEvents;
}
public override ADEventType Type { get; }
public string PerfectTag { get; set; }
public string HitTag { get; set; }
public string EarlyPerfectTag { get; set; }
public string LatePerfectTag { get; set; }
public string BarelyTag { get; set; }
public string VeryEarlyTag { get; set; }
public string VeryLateTag { get; set; }
public string MissTag { get; set; }
public string TooEarlyTag { get; set; }
public string TooLateTag { get; set; }
public string LossTag { get; set; }
public string OnCheckpointTag { get; set; }
}
}
@@ -0,0 +1,34 @@
using System;
using Newtonsoft.Json;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class ADSetDefaultText : ADBaseTaggedTileAction, IEaseEvent
{
public ADSetDefaultText()
{
Type = ADEventType.SetDefaultText;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public EaseType Ease { get; set; }
public RDColor? DefaultTextColor { get; set; }
public RDColor? DefaultTextShadowColor { get; set; }
public RDPoint? LevelTitlePosition { get; set; }
public string LevelTitleText { get; set; }
public string CongratsText { get; set; }
public string PerfectText { get; set; }
}
}
@@ -0,0 +1,73 @@
using System;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADSetFilter : ADBaseTaggedTileAction, IEaseEvent
{
public ADSetFilter()
{
Type = ADEventType.SetFilter;
}
public override ADEventType Type { get; }
public Filters Filter { get; set; }
public string Enabled { get; set; }
public int Intensity { get; set; }
public float Duration { get; set; }
public EaseType Ease { get; set; }
public string DisableOthers { get; set; }
public enum Filters
{
Grayscale,
Sepia,
Invert,
VHS,
EightiesTV,
FiftiesTV,
Arcade,
LED,
Rain,
Blizzard,
PixelSnow,
Compression,
Glitch,
Pixelate,
Waves,
Static,
Grain,
MotionBlur,
Fisheye,
Aberration,
Drawing,
Neon,
Handheld,
NightVision,
Funk,
Tunnel,
Weird3D,
Blur,
BlurFocus,
GaussianBlur,
HexagonBlack,
Posterize,
Sharpen,
Contrast,
EdgeBlackLine,
OilPaint,
SuperDot,
WaterDrop,
LightWater,
Petals,
PetalsInstant
}
}
}
@@ -0,0 +1,25 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetHitsound : ADBaseTileEvent
{
public ADSetHitsound()
{
Type = ADEventType.SetHitsound;
}
public override ADEventType Type { get; }
public string GameSound { get; set; }
public string Hitsound { get; set; }
public int HitsoundVolume { get; set; }
public enum GameSounds
{
Hitsound,
Midspin
}
}
}
@@ -0,0 +1,29 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetHoldSound : ADBaseTileEvent
{
public ADSetHoldSound()
{
Type = ADEventType.SetHoldSound;
}
public override ADEventType Type { get; }
public string HoldStartSound { get; set; }
public string HoldLoopSound { get; set; }
public string HoldEndSound { get; set; }
public string HoldMidSound { get; set; }
public string HoldMidSoundType { get; set; }
public float HoldMidSoundDelay { get; set; }
public string HoldMidSoundTimingRelativeTo { get; set; }
public int HoldSoundVolume { get; set; }
}
}
@@ -0,0 +1,34 @@
using Newtonsoft.Json;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
public class ADSetObject : ADBaseTaggedTileAction, IEaseEvent
{
public ADSetObject()
{
Type = ADEventType.SetObject;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public string Tag { get; set; }
public EaseType Ease { get; set; }
public RDColor? PlanetColor { get; set; }
public RDColor? PlanetTailColor { get; set; }
public float? TrackAngle { get; set; }
public ADTrackColorTypes? TrackColorType { get; set; }
public RDColor? TrackColor { get; set; }
public RDColor? SecondaryTrackColor { get; set; }
public float? TrackColorAnimDuration { get; set; }
public float? TrackOpacity { get; set; }
public ADTrackStyles? TrackStyle { get; set; }
public string TrackIcon { get; set; }
public float? TrackIconAngle { get; set; }
public bool? TrackRedSwirl { get; set; }
public bool? TrackGraySetSpeedIcon { get; set; }
public bool? TrackGlowEnabled { get; set; }
public RDColor? TrackGlowColor { get; set; }
}
}
@@ -0,0 +1,19 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetPlanetRotation : ADBaseTileEvent
{
public ADSetPlanetRotation()
{
Type = ADEventType.SetPlanetRotation;
}
public override ADEventType Type { get; }
public string Ease { get; set; }
public int EaseParts { get; set; }
public ADEasePartBehaviors EasePartBehavior { get; set; }
}
}
@@ -0,0 +1,25 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetSpeed : ADBaseTaggedTileAction
{
public ADSetSpeed()
{
Type = ADEventType.SetSpeed;
}
public override ADEventType Type { get; }
public SpeedTypes SpeedType { get; set; }
public float BeatsPerMinute { get; set; }
public float BpmMultiplier { get; set; }
public enum SpeedTypes
{
Bpm,
Multiplier
}
}
}
+17
View File
@@ -0,0 +1,17 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADSetText : ADBaseTaggedTileAction
{
public ADSetText()
{
Type = ADEventType.SetText;
}
public override ADEventType Type { get; }
public string DecText { get; set; }
public string Tag { get; set; }
}
}
@@ -0,0 +1,26 @@
using System;
using RhythmBase.Components;
using RhythmBase.Components.Easing;
using RhythmBase.Events;
namespace RhythmBase.Adofai.Events
{
public class ADShakeScreen : ADBaseTaggedTileAction, IEaseEvent
{
public ADShakeScreen()
{
Type = ADEventType.ShakeScreen;
}
public override ADEventType Type { get; }
public float Duration { get; set; }
public float Strength { get; set; }
public float Intensity { get; set; }
public EaseType Ease { get; set; }
public float FadeOut { get; set; }
}
}
+35
View File
@@ -0,0 +1,35 @@
using Newtonsoft.Json;
using RhythmBase.Adofai.Components;
namespace RhythmBase.Adofai.Events
{
public class ADTile : ADTypedList<ADBaseTileEvent>
{
public float Angle
{
get => _angle;
set => _angle = value is > (-360f) and < 360f ? ((value + 540f) % 360f) - 180f : -999f;
}
public bool IsMidSpin => _angle < -180f || _angle > 180f;
public ADBeat Beat => new(Parent?.Calculator!, Index + (_angle / 180f));
[JsonIgnore]
public ADLevel? Parent { get; set; }
public ADTile() { }
public ADTile(IEnumerable<ADBaseTileEvent> actions)
{
foreach (ADBaseTileEvent i in actions)
{
i.Parent = this;
Add(i);
}
}
public int Index => Parent?.IndexOf(this) ?? -1;
public override string ToString() => string.Format("[{0}]{1}<{2}>{3}",
[
Index,
Beat,
IsMidSpin ? "MS".PadRight(4) : _angle.ToString().PadLeft(4),
((IEnumerable<ADBaseTileEvent>)this).Any<ADBaseTileEvent>() ? string.Format(", Count = {0}", ((IEnumerable<ADBaseTileEvent>)this).Count<ADBaseTileEvent>()) : string.Empty
]);
private float _angle = 0;
}
}
@@ -0,0 +1,10 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADTileRelativeTo
{
ThisTile,
Start,
End
}
}
@@ -0,0 +1,10 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADTrackColorPulses
{
None,
Forward,
Backward
}
}
@@ -0,0 +1,14 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADTrackColorTypes
{
Single,
Stripes,
Glow,
Blink,
Switch,
Rainbow,
Volume
}
}
@@ -0,0 +1,13 @@
using System;
namespace RhythmBase.Adofai.Events
{
public enum ADTrackStyles
{
Standard,
Neon,
NeonLight,
Basic,
Gems,
Minimal
}
}
+13
View File
@@ -0,0 +1,13 @@
using System;
namespace RhythmBase.Adofai.Events
{
public class ADTwirl : ADBaseTileEvent
{
public ADTwirl()
{
Type = ADEventType.Twirl;
}
public override ADEventType Type { get; }
}
}
@@ -0,0 +1,37 @@
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Events;
using RhythmBase.Extensions;
namespace RhythmBase.Adofai.Utils
{
/// <summary>
/// Beat Calculator.
/// </summary>
public class ADBeatCalculator
{
internal ADBeatCalculator(ADLevel level)
{
Collection = level;
Refresh();
}
private void Refresh()
{
_DefaultBpm = Collection.Settings.Bpm;
_MidSpins = Collection.Where((i) => i.IsMidSpin).ToList();
////this._SetSpeeds = this.Collection.EventsWhere<ADSetSpeed>().ToList<ADSetSpeed>();
////this._Twirls = this.Collection.EventsWhere<ADTwirl>().ToList<ADTwirl>();
////this._Pauses = this.Collection.EventsWhere<ADPause>().ToList<ADPause>();
////this._Holds = this.Collection.EventsWhere<ADHold>().ToList<ADHold>();
////this._Freeroams = this.Collection.EventsWhere<ADFreeRoam>().ToList<ADFreeRoam>();
}
#pragma warning disable IDE0052 // 删除未读的私有成员
internal ADLevel Collection;
private float _DefaultBpm = 100;
private List<ADTile> _MidSpins = [];
private readonly List<ADSetSpeed> _SetSpeeds = [];
private readonly List<ADTwirl> _Twirls = [];
private readonly List<ADPause> _Pauses = [];
private readonly List<ADHold> _Holds = [];
private readonly List<ADFreeRoam> _Freeroams = [];
#pragma warning restore IDE0052 // 删除未读的私有成员
}
}
+154
View File
@@ -0,0 +1,154 @@
using Microsoft.VisualBasic.CompilerServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using RhythmBase.Adofai.Components;
using RhythmBase.Adofai.Converters;
using RhythmBase.Adofai.Events;
using RhythmBase.Converters;
using RhythmBase.Events;
using RhythmBase.Exceptions;
using RhythmBase.Settings;
using System.Collections.ObjectModel;
namespace RhythmBase.Adofai.Utils
{
/// <summary>
/// Useful utils.
/// </summary>
[StandardModule]
public static class Utils
{
/// <summary>
/// Converts a given type to an ADEventType enumeration.
/// </summary>
/// <param name="type">The type to convert.</param>
/// <returns>The corresponding ADEventType enumeration.</returns>
/// <exception cref="IllegalEventTypeException">Thrown when no matching EventType is found or multiple matching EventTypes are found.</exception>
public static ADEventType ADConvertToEnum(Type type)
{
if (ADETypesToEnum == null)
{
if (type.Name.StartsWith("AD"))
{
string name = type.Name[2..];
if (Enum.TryParse(name, out ADEventType result))
return result;
}
throw new IllegalEventTypeException(type, "Unable to find a matching EventType.");
}
ADEventType ADConvertToEnum;
try
{
ADConvertToEnum = ADETypesToEnum![type].Single();
}
catch
{
throw new IllegalEventTypeException(type, "Multiple matching EventTypes were found. Please check if the type is an abstract class type.", new ArgumentException("Multiple matching EventTypes were found. Please check if the type is an abstract class type.", nameof(type)));
}
return ADConvertToEnum;
}
/// <summary>
/// Converts a generic type to an ADEventType enumeration.
/// </summary>
/// <typeparam name="T">The type to convert, which must inherit from ADBaseEvent and have a parameterless constructor.</typeparam>
/// <returns>The corresponding ADEventType enumeration.</returns>
public static ADEventType ConvertToADEnum<T>() where T : ADBaseEvent, new() => ADConvertToEnum(typeof(T));
/// <summary>
/// Converts a generic type to an array of ADEventType enumerations.
/// </summary>
/// <typeparam name="T">The type to convert, which must inherit from BaseEvent.</typeparam>
/// <returns>An array of corresponding ADEventType enumerations.</returns>
/// <exception cref="IllegalEventTypeException">Thrown when no matching EventType is found.</exception>
public static ADEventType[] ConvertToADEnums<T>() where T : BaseEvent
{
ADEventType[] ConvertToADEnums;
try
{
ConvertToADEnums = ADETypesToEnum[typeof(T)];
}
catch
{
throw new IllegalEventTypeException(typeof(T), "This exception is not expected. Please contact the developer to handle this exception.");
}
return ConvertToADEnums;
}
/// <summary>
/// Converts a string representation of an ADEventType to a Type.
/// </summary>
/// <param name="type">The string representation of the ADEventType.</param>
/// <returns>The corresponding Type.</returns>
public static Type ADConvertToType(string type)
{
bool flag = Enum.TryParse(type, out ADEventType result);
Type ADConvertToType;
if (flag)
ADConvertToType = ConvertToType(result);
else
ADConvertToType = ConvertToType(ADEventType.CustomEvent);
return ADConvertToType;
}
/// <summary>
/// Converts an ADEventType enumeration to a Type.
/// </summary>
/// <param name="type">The ADEventType enumeration to convert.</param>
/// <returns>The corresponding Type.</returns>
/// <exception cref="RhythmBaseException">Thrown when the type is illegal.</exception>
/// <exception cref="IllegalEventTypeException">Thrown when the value does not exist in the EventType enumeration.</exception>
public static Type ConvertToType(this ADEventType type)
{
Type ConvertToType;
if (ADEnumToEType == null)
ConvertToType = Type.GetType(string.Format("{0}.AD{1}", typeof(ADBaseEvent).Namespace, type))
?? throw new RhythmBaseException(string.Format("Illegal Type: {0}.", type));
else
try
{
ConvertToType = ADEnumToEType[type];
}
catch
{
throw new IllegalEventTypeException(Conversions.ToString((int)type), "This value does not exist in the EventType enumeration.");
}
return ConvertToType;
}
/// <summary>
/// Gets a JsonSerializer configured with the necessary converters for the given ADLevel and settings.
/// </summary>
/// <param name="adlevel">The ADLevel instance.</param>
/// <param name="settings">The LevelReadOrWriteSettings instance.</param>
/// <returns>A configured JsonSerializer instance.</returns>
public static JsonSerializer GetSerializer(this ADLevel adlevel, LevelReadOrWriteSettings settings)
{
JsonSerializer AllInOneSerializer = new();
JsonConverterCollection converters = AllInOneSerializer.Converters;
converters.Add(new StringEnumConverter());
converters.Add(new ColorConverter());
converters.Add(new ADTileConverter(adlevel));
converters.Add(new ADCustomTileEventConverter(adlevel, settings));
converters.Add(new ADCustomEventConverter(adlevel, settings));
converters.Add(new ADBaseTileEventConverter<ADBaseTileEvent>(adlevel, settings));
converters.Add(new ADBaseEventConverter<ADBaseEvent>(adlevel, settings));
return AllInOneSerializer;
}
private static readonly ReadOnlyCollection<Type> ADETypes = (from i in typeof(ADBaseEvent).Assembly.GetTypes()
where i.IsAssignableTo(typeof(ADBaseEvent))
select i).ToList().AsReadOnly();
/// <summary>
/// A dictionary that records the correspondence of ADEventType to event types inheriting from ADBaseEvent.
/// </summary>
public static readonly ReadOnlyDictionary<Type, ADEventType[]> ADETypesToEnum = ADETypes.ToDictionary((Type i) => i, (Type i) => (from j in ADETypes
where (j == i || j.IsAssignableTo(i)) && !j.IsAbstract
select j).Select((Type j) => ADConvertToEnum(j)).ToArray()).AsReadOnly();
/// <summary>
/// A dictionary that records the correspondence of event types inheriting from ADBaseEvent to ADEventType.
/// </summary>
public static readonly ReadOnlyDictionary<ADEventType, Type> ADEnumToEType = Enum.GetValues<ADEventType>().ToDictionary((ADEventType i) => i, ConvertToType).AsReadOnly();
}
}