Archived
forked from RDTKEditor/RDTKEditor
添加对 Core 的直接引用
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
using RhythmBase.Components;
|
||||
using RhythmBase.Components.Easing;
|
||||
using System.Reflection;
|
||||
using static RhythmBase.Extensions.Extensions;
|
||||
|
||||
namespace RhythmBase.Events
|
||||
{
|
||||
public partial class CallCustomMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a series of default custom method implementations.
|
||||
/// </summary>
|
||||
public static class Shared
|
||||
{
|
||||
#pragma warning disable CS1591
|
||||
public static CallCustomMethod PropertyAssignment(string propertyName, bool value) => new() { MethodName = $"{propertyName.ToLowerCamelCase()} = {value}" };
|
||||
public static CallCustomMethod RoomPropertyAssignment(byte room, string propertyName, bool value) => new() { MethodName = $"room[{room}].{propertyName.ToLowerCamelCase()} = {value}" };
|
||||
public static CallCustomMethod FunctionCalling(string functionName, params object[] @params) => new() { MethodName = $"{functionName}({ArgumentCombining(@params)})" };
|
||||
private static string ArgumentCombining(params object[] @params) => $"{string.Join(", ", @params.Select(i =>
|
||||
i.GetType() == typeof(string) || i.GetType().IsEnum
|
||||
? $"str:{i}"
|
||||
: i.ToString() ?? ""))}";
|
||||
public static CallCustomMethod RoomFunctionCalling(byte room, string functionName, params object[] @params) => new() { MethodName = $"room[{room}].{functionName}({ArgumentCombining(@params)})" };
|
||||
private static CallCustomMethod VfxFunctionCalling(string functionName, params object[] @params) => new() { MethodName = $"vfx.{functionName}({ArgumentCombining(@params)})" };
|
||||
public static CallCustomMethod SetScoreboardLights(bool Mode, string Text) => FunctionCalling(nameof(SetScoreboardLights), Mode, Text);
|
||||
public static CallCustomMethod InvisibleChars(bool value) => PropertyAssignment(nameof(InvisibleChars), value);
|
||||
public static CallCustomMethod InvisibleHeart(bool value) => PropertyAssignment(nameof(InvisibleHeart), value);
|
||||
public static CallCustomMethod NoHitFlashBorder(bool value) => PropertyAssignment(nameof(NoHitFlashBorder), value);
|
||||
public static CallCustomMethod NoHitStrips(bool value) => PropertyAssignment(nameof(NoHitStrips), value);
|
||||
public static CallCustomMethod SetOneshotType(int rowID, ShockWaveType wavetype) => FunctionCalling(nameof(SetOneshotType), rowID, wavetype);
|
||||
public static CallCustomMethod WobblyLines(bool value) => PropertyAssignment(nameof(WobblyLines), value);
|
||||
public static CallCustomMethod ShockwaveSizeMultiplier(bool value) => PropertyAssignment(nameof(ShockwaveSizeMultiplier), value);
|
||||
public static CallCustomMethod ShockwaveDistortionMultiplier(bool value) => PropertyAssignment(nameof(ShockwaveDistortionMultiplier), value);
|
||||
public static CallCustomMethod ShockwaveDurationMultiplier(bool value) => PropertyAssignment(nameof(ShockwaveDurationMultiplier), value);
|
||||
public static CallCustomMethod MistakeOrHeal(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHeal), damageOrHeal);
|
||||
public static CallCustomMethod MistakeOrHealP1(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHealP1), damageOrHeal);
|
||||
public static CallCustomMethod MistakeOrHealP2(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHealP2), damageOrHeal);
|
||||
public static CallCustomMethod MistakeOrHealSilent(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHealSilent), damageOrHeal);
|
||||
public static CallCustomMethod MistakeOrHealP1Silent(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHealP1Silent), damageOrHeal);
|
||||
public static CallCustomMethod MistakeOrHealP2Silent(float damageOrHeal) => FunctionCalling(nameof(MistakeOrHealP2Silent), damageOrHeal);
|
||||
public static CallCustomMethod SetMistakeWeight(int rowID, float weight) => FunctionCalling(nameof(SetMistakeWeight), rowID, weight);
|
||||
public static CallCustomMethod DamageHeart(int rowID, float damage) => FunctionCalling(nameof(DamageHeart), rowID, damage);
|
||||
public static CallCustomMethod HealHeart(int rowID, float damage) => FunctionCalling(nameof(HealHeart), rowID, damage);
|
||||
public static CallCustomMethod WavyRowsAmplitude(byte roomID, float amplitude) => RoomPropertyAssignment(roomID, nameof(WavyRowsAmplitude), amplitude != 0f);
|
||||
public static CallCustomMethod WavyRowsFrequency(byte roomID, float frequency) => RoomPropertyAssignment(roomID, nameof(WavyRowsFrequency), frequency != 0f);
|
||||
public static CallCustomMethod SetShakeIntensityOnHit(byte roomID, int number, int strength) => RoomFunctionCalling(roomID, nameof(SetShakeIntensityOnHit), number, strength);
|
||||
public static CallCustomMethod ShowPlayerHand(byte roomID, bool isPlayer1, bool isShortArm, bool isInstant) => FunctionCalling(nameof(ShowPlayerHand), roomID, isPlayer1, isShortArm, isInstant);
|
||||
public static CallCustomMethod TintHandsWithInts(byte roomID, float R, float G, float B, float A) => FunctionCalling(nameof(TintHandsWithInts), roomID, R, G, B, A);
|
||||
public static CallCustomMethod SetHandsBorderColor(byte roomID, float R, float G, float B, float A, int style) => FunctionCalling(nameof(SetHandsBorderColor), roomID, R, G, B, A, style);
|
||||
public static CallCustomMethod SetAllHandsBorderColor(float R, float G, float B, float A, int style) => FunctionCalling(nameof(SetAllHandsBorderColor), R, G, B, A, style);
|
||||
public static CallCustomMethod SetHandToP1(int room, bool rightHand) => FunctionCalling(nameof(SetHandToP1), room, rightHand);
|
||||
public static CallCustomMethod SetHandToP2(int room, bool rightHand) => FunctionCalling(nameof(SetHandToP2), room, rightHand);
|
||||
public static CallCustomMethod SetHandToIan(int room, bool rightHand) => FunctionCalling(nameof(SetHandToIan), room, rightHand);
|
||||
public static CallCustomMethod SetHandToPaige(int room, bool rightHand) => FunctionCalling(nameof(SetHandToPaige), room, rightHand);
|
||||
public static CallCustomMethod SetShadowRow(int mimickerRowID, int mimickedRowID) => FunctionCalling(nameof(SetShadowRow), mimickerRowID, mimickedRowID);
|
||||
public static CallCustomMethod UnsetShadowRow(int mimickerRowID, int mimickedRowID) => FunctionCalling(nameof(UnsetShadowRow), mimickerRowID, mimickedRowID);
|
||||
public static CallCustomMethod ShakeCam(int number, int strength, int roomID) => VfxFunctionCalling(nameof(ShakeCam), number, strength, roomID);
|
||||
public static CallCustomMethod StopShakeCam(int roomID) => VfxFunctionCalling(nameof(StopShakeCam), roomID);
|
||||
public static CallCustomMethod ShakeCamSmooth(int duration, int strength, int roomID) => VfxFunctionCalling(nameof(ShakeCamSmooth), duration, strength, roomID);
|
||||
public static CallCustomMethod ShakeCamRotate(int duration, int strength, int roomID) => VfxFunctionCalling(nameof(ShakeCamRotate), duration, strength, roomID);
|
||||
public static CallCustomMethod SetKaleidoscopeColor(int roomID, float R1, float G1, float B1, float R2, float G2, float B2) => FunctionCalling(nameof(SetKaleidoscopeColor), roomID, R1, G1, B1, R2, G2, B2);
|
||||
public static CallCustomMethod SyncKaleidoscopes(int targetRoomID, int otherRoomID) => FunctionCalling(nameof(SyncKaleidoscopes), targetRoomID, otherRoomID);
|
||||
public static CallCustomMethod SetVignetteAlpha(float alpha, int roomID) => VfxFunctionCalling(nameof(SetVignetteAlpha), alpha, roomID);
|
||||
public static CallCustomMethod NoOneshotShadows(bool value) => PropertyAssignment(nameof(NoOneshotShadows), value);
|
||||
public static CallCustomMethod EnableRowReflections(int roomID) => FunctionCalling(nameof(EnableRowReflections), roomID);
|
||||
public static CallCustomMethod DisableRowReflections(int roomID) => FunctionCalling(nameof(DisableRowReflections), roomID);
|
||||
public static CallCustomMethod ChangeCharacter(string Name, int roomID) => FunctionCalling(nameof(ChangeCharacter), Name, roomID);
|
||||
public static CallCustomMethod ChangeCharacter(RDCharacters Name, int roomID) => FunctionCalling(nameof(ChangeCharacter), Name, roomID);
|
||||
public static CallCustomMethod ChangeCharacterSmooth(string Name, int roomID) => FunctionCalling(nameof(ChangeCharacterSmooth), Name, roomID);
|
||||
public static CallCustomMethod ChangeCharacterSmooth(RDCharacters Name, int roomID) => FunctionCalling(nameof(ChangeCharacterSmooth), Name, roomID);
|
||||
public static CallCustomMethod SmoothShake(bool value) => PropertyAssignment(nameof(SmoothShake), value);
|
||||
public static CallCustomMethod RotateShake(bool value) => PropertyAssignment(nameof(RotateShake), value);
|
||||
public static CallCustomMethod DisableRowChangeWarningFlashes(bool value) => PropertyAssignment(nameof(DisableRowChangeWarningFlashes), value);
|
||||
public static CallCustomMethod StatusSignWidth(float value) => PropertyAssignment(nameof(StatusSignWidth), value != 0f);
|
||||
public static CallCustomMethod SkippableRankScreen(bool value) => PropertyAssignment(nameof(SkippableRankScreen), value);
|
||||
public static CallCustomMethod MissesToCrackHeart(int value) => PropertyAssignment(nameof(MissesToCrackHeart), value != 0);
|
||||
public static CallCustomMethod SkipRankText(bool value) => PropertyAssignment(nameof(SkipRankText), value);
|
||||
public static CallCustomMethod AlternativeMatrix(bool value) => PropertyAssignment(nameof(AlternativeMatrix), value);
|
||||
public static CallCustomMethod ToggleSingleRowReflections(byte room, byte row, bool value) => FunctionCalling(nameof(ToggleSingleRowReflections), room, row, value);
|
||||
public static CallCustomMethod SetScrollSpeed(byte roomID, float speed, float duration, EaseType ease) => RoomFunctionCalling(roomID, nameof(SetScrollSpeed), speed, duration, ease);
|
||||
public static CallCustomMethod SetScrollOffset(byte roomID, float cameraOffset, float duration, EaseType ease) => RoomFunctionCalling(roomID, nameof(SetScrollOffset), cameraOffset, duration, ease);
|
||||
public static CallCustomMethod DarkenedRollerdisco(byte roomID, float value) => RoomFunctionCalling(roomID, nameof(DarkenedRollerdisco), value);
|
||||
public static CallCustomMethod CurrentSongVol(float targetVolume, float fadeTimeSeconds) => FunctionCalling(nameof(CurrentSongVol), targetVolume, fadeTimeSeconds);
|
||||
public static CallCustomMethod PreviousSongVol(float targetVolume, float fadeTimeSeconds) => FunctionCalling(nameof(PreviousSongVol), targetVolume, fadeTimeSeconds);
|
||||
public static CallCustomMethod EditTree(byte room, string property, float value, float beats, EaseType ease) => RoomFunctionCalling(room, nameof(EditTree), property, value, beats, ease);
|
||||
public static IEnumerable<CallCustomMethod> EditTree(byte room, ProceduralTree treeProperties, float beats, EaseType ease)
|
||||
{
|
||||
List<CallCustomMethod> L = [];
|
||||
foreach (FieldInfo p in typeof(ProceduralTree).GetFields())
|
||||
{
|
||||
float? value = (float?)p.GetValue(treeProperties);
|
||||
if (value != null)
|
||||
L.Add(EditTree(room, p.Name.ToLowerCamelCase(), (float)value, beats, ease));
|
||||
}
|
||||
return L;
|
||||
}
|
||||
public static CallCustomMethod EditTreeColor(byte room, bool location, string color, float beats, EaseType ease) => RoomFunctionCalling(room, nameof(EditTreeColor), location, color, beats, ease);
|
||||
public struct ProceduralTree
|
||||
{
|
||||
/// <summary>
|
||||
/// 过程树的属性
|
||||
/// </summary>
|
||||
public float?
|
||||
BrachedPerlteration,
|
||||
BranchesPerDivision,
|
||||
IterationsPerSecond,
|
||||
Thickness,
|
||||
TargetLength,
|
||||
MaxDeviation,
|
||||
Angle,
|
||||
CamAngle,
|
||||
CamDistance,
|
||||
CamDegreesPerSecond,
|
||||
CamSpeed,
|
||||
PulseIntensity,
|
||||
PulseRate,
|
||||
PulseWavelength;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using RhythmBase.Components;
|
||||
using RhythmBase.Components.Easing;
|
||||
using static RhythmBase.Extensions.Extensions;
|
||||
|
||||
namespace RhythmBase.Events
|
||||
{
|
||||
public partial class Comment
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains a series of default custom method implementations.
|
||||
/// </summary>
|
||||
public static class Shared
|
||||
{
|
||||
#pragma warning disable CS1591
|
||||
private static Comment FunctionCalling(string name, params object[] @params) => new() { Text = $"()=>{name.ToLowerCamelCase()}({string.Join(',', @params.Select(i => i.ToString()))})" };
|
||||
public static Comment TrueCameraMove(int RoomID, RDPointN p, float AnimationDuration, EaseType Ease) => FunctionCalling("TrueCameraMove", (byte)RoomID, p.X, p.Y, AnimationDuration, Ease);
|
||||
public static Comment Create(Particle particleName, RDPointN p) => FunctionCalling("Create", $"CustomParticles/{particleName}", p.X, p.Y);
|
||||
public static Comment Shockwave(ShockWaveType type, float value) => FunctionCalling("Shockwave", type, value);
|
||||
public static Comment WavyRowsAmplitude(byte roomID, float amplitude, float duration) => FunctionCalling("WavyRowsAmplitude", roomID, amplitude, duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using RhythmBase.Components;
|
||||
using RhythmBase.Components.Easing;
|
||||
using RhythmBase.Events;
|
||||
using System.Reflection;
|
||||
namespace RhythmBase.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for retrieving easing properties from events.
|
||||
/// </summary>
|
||||
public static class EasePropertyExtensions
|
||||
{
|
||||
private static readonly Dictionary<Type, PropertyInfo[]> EaseProperties = [];
|
||||
/// <summary>
|
||||
/// Retrieves the easing properties of the specified type of event.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEvent">The type of the event that implements <see cref="IEaseEvent"/>.</typeparam>
|
||||
/// <param name="obj">The collection of events to retrieve the easing properties from.</param>
|
||||
/// <returns>A dictionary containing the names and corresponding easing properties of the specified event type.</returns>
|
||||
/// <exception cref="NotSupportedException">Thrown when an unsupported property type is encountered.</exception>
|
||||
public static Dictionary<string, IEaseProperty> GetEaseProperties<TEvent>(this IEnumerable<TEvent> obj) where TEvent : IEaseEvent, new()
|
||||
{
|
||||
if (!EaseProperties.TryGetValue(typeof(TEvent), out PropertyInfo[]? properties))
|
||||
{
|
||||
EaseProperties[obj.GetType()] = properties = typeof(TEvent).GetProperties(BindingFlags.Instance | BindingFlags.Public)
|
||||
.Where(p => p.GetCustomAttribute<EasePropertyAttribute>() != null)
|
||||
.ToArray();
|
||||
}
|
||||
Dictionary<string, IEaseProperty> values = [];
|
||||
foreach (var property in properties)
|
||||
{
|
||||
if (property.PropertyType.IsAssignableFrom(typeof(RDExpression)))
|
||||
{
|
||||
values[property.Name] = EasePropertyFloat.CreateEaseProperty(0, [.. obj], property);
|
||||
}
|
||||
else if (property.PropertyType.IsAssignableFrom(typeof(RDPointE)))
|
||||
{
|
||||
values[property.Name] = EasePropertyPoint.CreateEaseProperty(default, [.. obj], property);
|
||||
}
|
||||
else if (property.PropertyType.IsAssignableFrom(typeof(RDSizeE)))
|
||||
{
|
||||
values[property.Name] = EasePropertySize.CreateEaseProperty(default, [.. obj], property);
|
||||
}
|
||||
else if (property.PropertyType.IsAssignableFrom(typeof(RDColor)))
|
||||
{
|
||||
values[property.Name] = EasePropertyColor.CreateEaseProperty(default, [.. obj], property);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"Unsupported property type {property.PropertyType}");
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,587 @@
|
||||
using RhythmBase.Components;
|
||||
using RhythmBase.Components.Easing;
|
||||
using RhythmBase.Events;
|
||||
using RhythmBase.Exceptions;
|
||||
using RhythmBase.Extensions;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace RhythmBase.Extensions
|
||||
{
|
||||
public static partial class Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the pulse sound effect of row beat event.
|
||||
/// </summary>
|
||||
/// <returns>The sound effect of row beat event.</returns>
|
||||
public static RDAudio BeatSound(this BaseBeat e)
|
||||
{
|
||||
SetBeatSound? setBeatSound = e.Parent?.LastOrDefault((SetBeatSound i) => i.Beat < e.Beat && i.Active);
|
||||
return (setBeatSound?.Sound) ?? e.Parent?.Sound ?? throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
/// Getting controlled events.
|
||||
/// </summary>
|
||||
public static IEnumerable<IGrouping<string, IBaseEvent>> ControllingEvents(this TagAction e) => e.Beat.BaseLevel?.GetTaggedEvents(e.ActionTag, e.Action.HasFlag(TagAction.Actions.All)) ?? [];
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="T:RhythmBase.Events.AdvanceText" /> subordinate to <see cref="T:RhythmBase.Events.FloatingText" /> at the specified beat. The new event created will be attempted to be added to the <see cref="T:RhythmBase.Events.FloatingText" />'s source level.
|
||||
/// </summary>
|
||||
/// <param name="e">RDLevel</param>
|
||||
/// <param name="beat">Specified beat.</param>
|
||||
public static AdvanceText CreateAdvanceText(this FloatingText e, RDBeat beat)
|
||||
{
|
||||
AdvanceText A = new()
|
||||
{
|
||||
Parent = e,
|
||||
Beat = beat.WithoutBinding()
|
||||
};
|
||||
e.Children.Add(A);
|
||||
return A;
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the end beat of the duration.
|
||||
/// </summary>
|
||||
/// <param name="beat"></param>
|
||||
/// <param name="duration"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidRDBeatException"></exception>
|
||||
public static RDBeat DurationOffset(this RDBeat beat, float duration)
|
||||
{
|
||||
SetBeatsPerMinute setBPM = beat.BaseLevel?.First((SetBeatsPerMinute i) => i.Beat > beat) ?? throw new InvalidRDBeatException();
|
||||
RDBeat DurationOffset =
|
||||
beat.BarBeat.bar == setBPM.Beat.BarBeat.bar
|
||||
? beat + duration
|
||||
: beat + TimeSpan.FromMinutes(duration / beat.BPM);
|
||||
return DurationOffset;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns the pulse beat of the specified 0-based index.
|
||||
/// </summary>
|
||||
/// <exception cref="T:RhythmBase.Exceptions.RhythmBaseException">THIS IS 7TH BEAT GAMES!</exception>
|
||||
public static RDBeat GetBeat(this AddClassicBeat e, byte index)
|
||||
{
|
||||
SetRowXs x = e.Parent?.LastOrDefault((SetRowXs i) => i.Active && e.IsBehind(i)) ?? new();
|
||||
float Synco = 0 <= x.SyncoBeat && x.SyncoBeat < (sbyte)index ? (float)((x.SyncoSwing == 0f) ? 0.5 : ((double)x.SyncoSwing)) : 0f;
|
||||
if (index >= 7)
|
||||
throw new RhythmBaseException("THIS IS 7TH BEAT GAMES!");
|
||||
return e.Beat.DurationOffset(e.Tick * ((float)index - Synco));
|
||||
}
|
||||
/// <summary>
|
||||
/// Converts Xs patterns to string form.
|
||||
/// </summary>
|
||||
public static string GetPatternString(this SetRowXs e) => Utils.Utils.GetPatternString(e.Pattern);
|
||||
/// <summary>
|
||||
/// Get the sequence of <see cref="T:RhythmBase.Events.PulseFreeTimeBeat" /> belonging to this <see cref="T:RhythmBase.Events.AddFreeTimeBeat" />, return all of the <see cref="T:RhythmBase.Events.PulseFreeTimeBeat" /> from the time the pulse was created to the time it was removed or hit.
|
||||
/// </summary>
|
||||
public static IEnumerable<PulseFreeTimeBeat> GetPulses(this AddFreeTimeBeat e)
|
||||
{
|
||||
List<PulseFreeTimeBeat> Result = [];
|
||||
byte pulse = e.Pulse;
|
||||
if (e.Parent == null)
|
||||
yield break;
|
||||
foreach (PulseFreeTimeBeat item in e.Parent.Where<PulseFreeTimeBeat>(i => i.Active && e.IsInFrontOf(i)))
|
||||
{
|
||||
switch (item.Action)
|
||||
{
|
||||
case PulseFreeTimeBeat.ActionType.Increment:
|
||||
pulse += 1;
|
||||
yield return item;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Decrement:
|
||||
pulse = (byte)((pulse > 0b1) ? (pulse - 0b1) : 0b1);
|
||||
yield return item;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Custom:
|
||||
pulse = (byte)item.CustomPulse;
|
||||
yield return item;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Remove:
|
||||
yield return item;
|
||||
break;
|
||||
}
|
||||
if (pulse == 6)
|
||||
break;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the hit sound effect of row beat event.
|
||||
/// </summary>
|
||||
/// <returns>The sound effect of row beat event.</returns>
|
||||
public static RDAudio HitSound(this BaseBeat e)
|
||||
{
|
||||
RDAudio DefaultAudio = new()
|
||||
{
|
||||
Filename = "sndClapHit",
|
||||
Offset = TimeSpan.Zero,
|
||||
Pan = 100,
|
||||
Pitch = 100,
|
||||
Volume = 100
|
||||
};
|
||||
RDAudio? HitSound;
|
||||
switch (e.Player())
|
||||
{
|
||||
case PlayerType.P1:
|
||||
{
|
||||
SetClapSounds? setClapSounds = e.Beat.BaseLevel?.LastOrDefault((SetClapSounds i) => i.Active && i.P1Sound != null);
|
||||
HitSound = (setClapSounds?.P1Sound) ?? DefaultAudio;
|
||||
break;
|
||||
}
|
||||
case PlayerType.P2:
|
||||
{
|
||||
SetClapSounds? setClapSounds2 = e.Beat.BaseLevel?.LastOrDefault((SetClapSounds i) => i.Active && i.P2Sound != null);
|
||||
HitSound = (setClapSounds2?.P2Sound) ?? DefaultAudio;
|
||||
break;
|
||||
}
|
||||
case PlayerType.CPU:
|
||||
{
|
||||
SetClapSounds? setClapSounds3 = e.Beat.BaseLevel?.LastOrDefault((SetClapSounds i) => i.Active && i.CpuSound != null);
|
||||
HitSound = (setClapSounds3?.CpuSound) ?? DefaultAudio;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
HitSound = DefaultAudio;
|
||||
break;
|
||||
}
|
||||
return HitSound;
|
||||
}
|
||||
/// <summary>
|
||||
/// Get all hits.
|
||||
/// </summary>
|
||||
public static IEnumerable<RDHit> HitTimes(this AddClassicBeat e) =>
|
||||
new List<RDHit> { new(e, e.GetBeat(6), e.Hold) }
|
||||
.AsEnumerable();
|
||||
/// <summary>
|
||||
/// Get all hits.
|
||||
/// </summary>
|
||||
public static IEnumerable<RDHit> HitTimes(this AddOneshotBeat e)
|
||||
{
|
||||
e._beat.IfNullThrowException();
|
||||
List<RDHit> L = [];
|
||||
uint loops = e.Loops;
|
||||
for (uint i = 0U; i <= loops; i += 1U)
|
||||
{
|
||||
sbyte b = (sbyte)(e.Subdivisions - 1);
|
||||
for (sbyte j = 0; j <= b; j += 1)
|
||||
L.Add(new RDHit(e, new RDBeat(e._beat._calculator, e._beat.BeatOnly + i * e.Interval + e.Tick + e.Delay + (float)j * (e.Tick / (float)e.Subdivisions)), 0f));
|
||||
}
|
||||
return L.AsEnumerable();
|
||||
}
|
||||
/// <summary>
|
||||
/// Get all hits.
|
||||
/// </summary>
|
||||
public static IEnumerable<RDHit> HitTimes(this AddFreeTimeBeat e) =>
|
||||
e.Pulse == 6
|
||||
? [new(e, e.Beat, e.Hold)]
|
||||
: ([]);
|
||||
/// <summary>
|
||||
/// Get all hits.
|
||||
/// </summary>
|
||||
public static IEnumerable<RDHit> HitTimes(this PulseFreeTimeBeat e) =>
|
||||
e.IsHitable()
|
||||
? [new(e, e.Beat, e.Hold)]
|
||||
: ([]);
|
||||
/// <summary>
|
||||
/// Get all hits.
|
||||
/// </summary>
|
||||
public static IEnumerable<RDHit> HitTimes(this BaseBeat e) => e.Type switch
|
||||
{
|
||||
EventType.AddClassicBeat => ((AddClassicBeat)e).HitTimes(),
|
||||
EventType.AddFreeTimeBeat => ((AddFreeTimeBeat)e).HitTimes(),
|
||||
EventType.AddOneshotBeat => ((AddOneshotBeat)e).HitTimes(),
|
||||
_ => e.Type != EventType.PulseFreeTimeBeat
|
||||
? Array.Empty<RDHit>().AsEnumerable()
|
||||
: ((PulseFreeTimeBeat)e).HitTimes(),
|
||||
};
|
||||
/// <summary>
|
||||
/// Determine if <paramref name="item1" /> is after <paramref name="item2" />
|
||||
/// </summary>
|
||||
/// <returns><list type="table">
|
||||
/// <item>If <paramref name="item1" /> is after <paramref name="item2" />, <see langword="true" /></item>
|
||||
/// <item>Else, <see langword="false" /></item>
|
||||
/// </list></returns>
|
||||
public static bool IsBehind(this OrderedEventCollection e, IBaseEvent item1, IBaseEvent item2) => (item1.Beat > item2.Beat || (item1.Beat.BeatOnly == item2.Beat.BeatOnly && (e.eventsBeatOrder[item1.Beat].BeforeThan(item2, item1))));
|
||||
/// <summary>
|
||||
/// Check if another event is after itself, including events of the same beat but executed after itself.
|
||||
/// </summary>
|
||||
public static bool IsBehind(this IBaseEvent e, IBaseEvent item) => e.Beat.BaseLevel?.IsBehind(e, item) ?? throw new InvalidRDBeatException();
|
||||
/// <summary>
|
||||
/// Check if it can be hit by player.
|
||||
/// </summary>
|
||||
public static bool IsHitable(this PulseFreeTimeBeat e)
|
||||
{
|
||||
int PulseIndexMin = 6;
|
||||
int PulseIndexMax = 6;
|
||||
if (e.Parent is null)
|
||||
return false;
|
||||
foreach (BaseBeat item in ((IEnumerable<BaseBeat>)e.Parent
|
||||
.Where(e.IsBehind, new RDRange(e.Beat, null)))
|
||||
.Reverse())
|
||||
{
|
||||
EventType type = item.Type;
|
||||
switch (type)
|
||||
{
|
||||
case EventType.AddFreeTimeBeat:
|
||||
{
|
||||
AddFreeTimeBeat Temp2 = (AddFreeTimeBeat)item;
|
||||
if (PulseIndexMin <= (int)Temp2.Pulse & (int)Temp2.Pulse <= PulseIndexMax)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
case EventType.PulseFreeTimeBeat:
|
||||
{
|
||||
PulseFreeTimeBeat Temp = (PulseFreeTimeBeat)item;
|
||||
switch (Temp.Action)
|
||||
{
|
||||
case PulseFreeTimeBeat.ActionType.Increment:
|
||||
if (PulseIndexMin > 0)
|
||||
PulseIndexMin--;
|
||||
if (!(PulseIndexMax > 0))
|
||||
return false;
|
||||
PulseIndexMax--;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Decrement:
|
||||
if (PulseIndexMin > 0)
|
||||
PulseIndexMin++;
|
||||
if (!(PulseIndexMax < 6))
|
||||
return false;
|
||||
PulseIndexMax++;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Custom:
|
||||
if (!(PulseIndexMin <= Temp.CustomPulse & Temp.CustomPulse <= PulseIndexMax))
|
||||
return false;
|
||||
PulseIndexMin = 0;
|
||||
PulseIndexMax = 5;
|
||||
break;
|
||||
case PulseFreeTimeBeat.ActionType.Remove:
|
||||
return false;
|
||||
}
|
||||
if (PulseIndexMin > PulseIndexMax)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Check if it can be hit by player.
|
||||
/// </summary>
|
||||
public static bool IsHitable(this AddFreeTimeBeat e) => e.Pulse == 6;
|
||||
/// <summary>
|
||||
/// Check if it can be hit by player.
|
||||
/// </summary>
|
||||
public static bool IsHitable(this BaseBeat e) => e.Type switch
|
||||
{
|
||||
EventType.AddClassicBeat or EventType.AddOneshotBeat => true,
|
||||
EventType.AddFreeTimeBeat => ((AddFreeTimeBeat)e).IsHitable(),
|
||||
_ => e.Type == EventType.PulseFreeTimeBeat && ((PulseFreeTimeBeat)e).IsHitable(),
|
||||
};
|
||||
/// <summary>
|
||||
/// Determine if <paramref name="item1" /> is in front of <paramref name="item2" />
|
||||
/// </summary>
|
||||
/// <returns><list type="table">
|
||||
/// <item>If <paramref name="item1" /> is in front of <paramref name="item2" />, <see langword="true" /></item>
|
||||
/// <item>Else, <see langword="false" /></item>
|
||||
/// </list></returns>
|
||||
public static bool IsInFrontOf(this OrderedEventCollection e, IBaseEvent item1, IBaseEvent item2) => (item1.Beat < item2.Beat || (item1.Beat.BeatOnly == item2.Beat.BeatOnly && (e.eventsBeatOrder[item1.Beat].BeforeThan(item1, item2))));
|
||||
/// <summary>
|
||||
/// Check if another event is in front of itself, including events of the same beat but executed before itself.
|
||||
/// </summary>
|
||||
public static bool IsInFrontOf(this IBaseEvent e, IBaseEvent item) => e.Beat.BaseLevel?.IsInFrontOf(e, item) ?? throw new InvalidRDBeatException();
|
||||
/// <summary>
|
||||
/// Get the total length of the oneshot.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static float Length(this AddOneshotBeat e) => e.Tick * e.Loops + e.Interval * e.Loops - 1f;
|
||||
/// <summary>
|
||||
/// Get the total length of the classic beat.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static float Length(this AddClassicBeat e)
|
||||
{
|
||||
float SyncoSwing = e.Parent?.LastOrDefault((SetRowXs i) => i.Active && e.IsBehind(i))?.SyncoSwing ?? 0;
|
||||
return (float)((double)(e.Tick * 6f) - ((SyncoSwing == 0f) ? 0.5 : ((double)SyncoSwing)) * (double)e.Tick);
|
||||
}
|
||||
/// <summary>
|
||||
/// Specifies the position of the image. This method changes both the pivot and the angle to keep the image visually in its original position.
|
||||
/// </summary>
|
||||
/// <param name="spriteSize">Sprite size. </param>
|
||||
/// <param name="e">RDLevel</param>
|
||||
/// <param name="target">Specified position. </param>
|
||||
public static void MovePositionMaintainVisual(this Move e, RDSizeE spriteSize, RDPointE target)
|
||||
{
|
||||
if (e.Position != null && e.Pivot != null && e.Angle != null && e.Angle.Value.IsNumeric)
|
||||
{
|
||||
e.Position = new RDPointE?(target);
|
||||
e.Pivot = new RDPointE?((e.VisualPosition(spriteSize) - new RDSizeE(target)).Rotate(e.Angle.Value.NumericValue));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Specifies the position of the image. This method changes both the pivot and the angle to keep the image visually in its original position.
|
||||
/// </summary>
|
||||
/// <param name="e">RDLevel</param>
|
||||
/// <param name="target">Specified position. </param>
|
||||
public static void MovePositionMaintainVisual(this MoveRoom e, RDSizeE target)
|
||||
{
|
||||
if (e.RoomPosition != null && e.Pivot != null && e.Angle != null && e.Angle.Value.IsNumeric)
|
||||
{
|
||||
e.RoomPosition = new RDPointE?((RDPointE)target);
|
||||
e.Pivot = new RDPointE?((e.VisualPosition() - new RDSizeE((RDPointE)target)).Rotate(e.Angle.Value.NumericValue));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Convert beat pattern to string.
|
||||
/// </summary>
|
||||
/// <returns>The pattern string.</returns>
|
||||
public static string Pattern(this AddClassicBeat e) => Utils.Utils.GetPatternString(e.RowXs());
|
||||
/// <summary>
|
||||
/// Get current player of the beat event.
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
public static PlayerType Player(this BaseBeat e)
|
||||
{
|
||||
ChangePlayersRows? changePlayersRows = e.Beat.BaseLevel?.LastOrDefault((ChangePlayersRows i) => i.Active && i.Players[e.Index] != PlayerType.NoChange);
|
||||
return (changePlayersRows != null)
|
||||
? changePlayersRows.Players[e.Index]
|
||||
: (PlayerType)(e.Parent?.Player ?? throw new NotImplementedException());
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the actual beat pattern.
|
||||
/// </summary>
|
||||
/// <returns>The actual beat pattern.</returns>
|
||||
public static Patterns[] RowXs(this AddClassicBeat e)
|
||||
{
|
||||
if (e.SetXs == null)
|
||||
{
|
||||
SetRowXs X = e.Parent?.LastOrDefault((SetRowXs i) => i.Active && e.IsBehind(i)) ?? new();
|
||||
return X.Pattern;
|
||||
}
|
||||
else
|
||||
{
|
||||
Patterns[] T = new Patterns[6];
|
||||
AddClassicBeat.ClassicBeatPatterns? setXs = e.SetXs;
|
||||
int? num = (setXs != null) ? new int?((int)setXs.GetValueOrDefault()) : null;
|
||||
if (((num != null) ? new bool?(num.GetValueOrDefault() == 0) : null).GetValueOrDefault())
|
||||
{
|
||||
T[1] = Patterns.X;
|
||||
T[2] = Patterns.X;
|
||||
T[4] = Patterns.X;
|
||||
T[5] = Patterns.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = (setXs != null) ? new int?((int)setXs.GetValueOrDefault()) : null;
|
||||
if (!(((num != null) ? new bool?(num.GetValueOrDefault() == 1) : null).GetValueOrDefault()))
|
||||
{
|
||||
throw new RhythmBaseException("How?");
|
||||
}
|
||||
T[1] = Patterns.X;
|
||||
T[3] = Patterns.X;
|
||||
T[5] = Patterns.X;
|
||||
}
|
||||
return T;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Get the special tag of the tag event.
|
||||
/// </summary>
|
||||
/// <returns>special tags.</returns>
|
||||
public static TagAction.SpecialTag[] SpetialTags(this TagAction e) => (TagAction.SpecialTag[])(from i in Enum.GetValues<TagAction.SpecialTag>()
|
||||
where e.ActionTag.Contains(string.Format("[{0}]", i))
|
||||
select i);
|
||||
/// <summary>
|
||||
/// Generate split event instances.
|
||||
/// </summary>
|
||||
public static IEnumerable<SayReadyGetSetGo> Split(this SayReadyGetSetGo e) => e.PhraseToSay switch
|
||||
{
|
||||
SayReadyGetSetGo.Words.SayReaDyGetSetGoNew => [
|
||||
e.SplitCopy(0f, SayReadyGetSetGo.Words.JustSayRea),
|
||||
e.SplitCopy(e.Tick, SayReadyGetSetGo.Words.JustSayDy),
|
||||
e.SplitCopy(e.Tick * 2f, SayReadyGetSetGo.Words.JustSayGet),
|
||||
e.SplitCopy(e.Tick * 3f, SayReadyGetSetGo.Words.JustSaySet),
|
||||
e.SplitCopy(e.Tick * 4f, SayReadyGetSetGo.Words.JustSayGo)
|
||||
],
|
||||
SayReadyGetSetGo.Words.SayGetSetGo => [
|
||||
e.SplitCopy(0f, SayReadyGetSetGo.Words.JustSayGet),
|
||||
e.SplitCopy(e.Tick, SayReadyGetSetGo.Words.JustSaySet),
|
||||
e.SplitCopy(e.Tick * 2f, SayReadyGetSetGo.Words.JustSayGo)
|
||||
],
|
||||
SayReadyGetSetGo.Words.SayReaDyGetSetOne => [
|
||||
e.SplitCopy(0f, SayReadyGetSetGo.Words.JustSayRea),
|
||||
e.SplitCopy(e.Tick, SayReadyGetSetGo.Words.JustSayDy),
|
||||
e.SplitCopy(e.Tick * 2f, SayReadyGetSetGo.Words.JustSayGet),
|
||||
e.SplitCopy(e.Tick * 3f, SayReadyGetSetGo.Words.JustSaySet),
|
||||
e.SplitCopy(e.Tick * 4f, SayReadyGetSetGo.Words.Count1)
|
||||
],
|
||||
SayReadyGetSetGo.Words.SayGetSetOne => [
|
||||
e.SplitCopy(0f, SayReadyGetSetGo.Words.JustSayGet),
|
||||
e.SplitCopy(e.Tick, SayReadyGetSetGo.Words.JustSaySet),
|
||||
e.SplitCopy(e.Tick * 2f, SayReadyGetSetGo.Words.Count1)
|
||||
],
|
||||
SayReadyGetSetGo.Words.SayReadyGetSetGo => [
|
||||
e.SplitCopy(0f, SayReadyGetSetGo.Words.JustSayReady),
|
||||
e.SplitCopy(e.Tick * 2f, SayReadyGetSetGo.Words.JustSayGet),
|
||||
e.SplitCopy(e.Tick * 3f, SayReadyGetSetGo.Words.JustSaySet),
|
||||
e.SplitCopy(e.Tick * 4f, SayReadyGetSetGo.Words.JustSayGo)
|
||||
],
|
||||
_ => [e],
|
||||
};
|
||||
/// <summary>
|
||||
/// Generate split event instances.
|
||||
/// </summary>
|
||||
public static IEnumerable<AddOneshotBeat> Split(this AddOneshotBeat e)
|
||||
{
|
||||
e._beat.IfNullThrowException();
|
||||
List<AddOneshotBeat> L = [];
|
||||
uint loops = e.Loops;
|
||||
for (uint i = 0U; i <= loops; i += 1U)
|
||||
{
|
||||
AddOneshotBeat T = e.MemberwiseClone();
|
||||
T.Loops = 0U;
|
||||
T.Interval = 0f;
|
||||
T.Beat = new RDBeat(e._beat._calculator, unchecked(e.Beat.BeatOnly + i * e.Interval));
|
||||
L.Add(T);
|
||||
}
|
||||
return L.AsEnumerable();
|
||||
}
|
||||
/// <summary>
|
||||
/// Generate split event instances. Follow the most recently activated Xs.
|
||||
/// </summary>
|
||||
public static IEnumerable<BaseBeat> Split(this AddClassicBeat e)
|
||||
{
|
||||
SetRowXs x = e.Parent?.LastOrDefault((SetRowXs i) => i.Active && e.IsBehind(i)) ?? new();
|
||||
return e.Split(x);
|
||||
}
|
||||
/// <summary>
|
||||
/// Generate split event instances.
|
||||
/// </summary>
|
||||
public static IEnumerable<BaseBeat> Split(this AddClassicBeat e, SetRowXs Xs)
|
||||
{
|
||||
List<BaseBeat> L = [];
|
||||
AddFreeTimeBeat Head = e.Clone<AddFreeTimeBeat>();
|
||||
Head.Pulse = 0;
|
||||
Head.Hold = e.Hold;
|
||||
L.Add(Head);
|
||||
int i = 1;
|
||||
do
|
||||
{
|
||||
if (!(i < 6 && Xs.Pattern[i] == Patterns.X))
|
||||
{
|
||||
PulseFreeTimeBeat Pulse = e.Clone<PulseFreeTimeBeat>();
|
||||
PulseFreeTimeBeat pulseFreeTimeBeat;
|
||||
(pulseFreeTimeBeat = Pulse).Beat = pulseFreeTimeBeat.Beat + e.Tick * (float)i;
|
||||
if (i >= (int)Xs.SyncoBeat)
|
||||
(pulseFreeTimeBeat = Pulse).Beat = pulseFreeTimeBeat.Beat - Xs.SyncoSwing;
|
||||
if (i % 2 == 1)
|
||||
(pulseFreeTimeBeat = Pulse).Beat = pulseFreeTimeBeat.Beat + (e.Tick - ((e.Swing == 0f) ? e.Tick : e.Swing));
|
||||
Pulse.Hold = e.Hold;
|
||||
Pulse.Action = PulseFreeTimeBeat.ActionType.Increment;
|
||||
L.Add(Pulse);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (i <= 6);
|
||||
return L.AsEnumerable();
|
||||
}
|
||||
/// <summary>
|
||||
/// Calculates the duration of the VFX effect for the given preset.
|
||||
/// </summary>
|
||||
/// <param name="e">The SetVFXPreset event.</param>
|
||||
/// <returns>An RDRange representing the duration of the VFX effect.</returns>
|
||||
public static RDRange VFXDuration(this SetVFXPreset e)
|
||||
{
|
||||
if (e.Preset != SetVFXPreset.Presets.DisableAll && e.Enable)
|
||||
{
|
||||
SetVFXPreset? close = e.After().FirstOrDefault(i =>
|
||||
i.Rooms.Contains(e.Rooms) && (
|
||||
i.Preset == e.Preset ||
|
||||
i.Preset == SetVFXPreset.Presets.DisableAll
|
||||
));
|
||||
return new(e.Beat, close?.Beat);
|
||||
}
|
||||
return new(e.Beat, e.Beat);
|
||||
}
|
||||
/// <summary>
|
||||
/// Remove auxiliary symbols.
|
||||
/// </summary>
|
||||
public static string TextOnly(this ShowDialogue e)
|
||||
{
|
||||
string result = e.Text;
|
||||
foreach (string item in new string[]
|
||||
{
|
||||
"shake",
|
||||
"shakeRadius=\\d+",
|
||||
"wave",
|
||||
"waveHeight=\\d+",
|
||||
"waveSpeed=\\d+",
|
||||
"swirl",
|
||||
"swirlRadius=\\d+",
|
||||
"swirlSpeed=\\d+",
|
||||
"static"
|
||||
})
|
||||
result = Regex.Replace(result, string.Format("\\[{0}\\]", item), "");
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// The visual position of the lower left corner of the image.
|
||||
/// </summary>
|
||||
public static RDPointE VisualPosition(this Move e, RDSizeE spriteSize)
|
||||
{
|
||||
RDPointE VisualPosition = default;
|
||||
if (e.Position != null && e.Pivot != null && e.Angle != null && e.Angle.Value.IsNumeric && e.Scale != null)
|
||||
{
|
||||
RDPointE previousPosition = e.Position.Value;
|
||||
RDExpression? x = e.Pivot?.X * (e.Scale?.Width) * spriteSize.Width / 100f;
|
||||
RDPointE previousPivot = new(x, e.Pivot?.Y * (e.Scale?.Height) * spriteSize.Height / 100f);
|
||||
VisualPosition = previousPosition + new RDSizeE(previousPivot.Rotate(e.Angle.Value.NumericValue));
|
||||
}
|
||||
return VisualPosition;
|
||||
}
|
||||
/// <summary>
|
||||
/// The visual position of the lower left corner of the image.
|
||||
/// </summary>
|
||||
public static RDPointE VisualPosition(this MoveRoom e)
|
||||
{
|
||||
RDPointE VisualPosition = default;
|
||||
if (e.RoomPosition != null && e.Pivot != null && e.Angle != null)
|
||||
{
|
||||
RDPointE previousPosition = e.RoomPosition.Value;
|
||||
RDPointE previousPivot = new((e.Pivot?.X) * (e.Scale?.Width), (e.Pivot?.Y) * (e.Scale?.Height));
|
||||
VisualPosition = previousPosition + new RDSizeE(previousPivot.Rotate(e.Angle.Value.NumericValue));
|
||||
}
|
||||
return VisualPosition;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a rotated rectangle for the MoveCamera event.
|
||||
/// </summary>
|
||||
/// <param name="e">The MoveCamera event.</param>
|
||||
/// <returns>A rotated rectangle representing the camera's position, zoom, and angle.</returns>
|
||||
public static RDRotatedRectE RotatedRect(this MoveCamera e) => new(e.CameraPosition, new(e.Zoom, e.Zoom), null, e.Angle);
|
||||
/// <summary>
|
||||
/// Creates a rotated rectangle for the MoveRow event.
|
||||
/// </summary>
|
||||
/// <param name="e">The MoveRow event.</param>
|
||||
/// <returns>A rotated rectangle representing the row's position, scale, pivot, and angle.</returns>
|
||||
public static RDRotatedRectE RotatedRect(this MoveRow e) => new(e.RowPosition, e.Scale, new(e.Pivot, e.Pivot), e.Angle);
|
||||
/// <summary>
|
||||
/// Creates a rotated rectangle for the MoveRoom event.
|
||||
/// </summary>
|
||||
/// <param name="e">The MoveRoom event.</param>
|
||||
/// <returns>A rotated rectangle representing the room's position, scale, pivot, and angle.</returns>
|
||||
public static RDRotatedRectE RotatedRect(this MoveRoom e) => new(e.RoomPosition, e.Scale, e.Pivot, e.Angle);
|
||||
/// <summary>
|
||||
/// Creates a rotated rectangle for the Move event.
|
||||
/// </summary>
|
||||
/// <param name="e">The Move event.</param>
|
||||
/// <returns>A rotated rectangle representing the position, scale, pivot, and angle.</returns>
|
||||
public static RDRotatedRectE RotatedRect(this Move e) => new(e.Position, e.Scale, e.Pivot, e.Angle);
|
||||
private static SayReadyGetSetGo SplitCopy(this SayReadyGetSetGo e, float extraBeat, SayReadyGetSetGo.Words word)
|
||||
{
|
||||
SayReadyGetSetGo Temp = e.Clone<SayReadyGetSetGo>();
|
||||
Temp.Beat += extraBeat;
|
||||
Temp.PhraseToSay = word;
|
||||
Temp.Volume = e.Volume;
|
||||
return Temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user