using Newtonsoft.Json; using RhythmBase.Converters; using RhythmBase.Events; using RhythmBase.Exceptions; namespace RhythmBase.Components { /// /// A collection of row events. /// [JsonObject] public class RowEventCollection : OrderedEventCollection { /// /// Gets or sets the character associated with the row. /// public RDCharacter Character { get; set; } /// /// Gets or sets the type of the row. /// public RowType RowType { get => _rowType; set { if (value != _rowType) { Clear(); _rowType = value; } } } /// /// Gets the index of the row. /// [JsonProperty("row", DefaultValueHandling = DefaultValueHandling.Include)] public sbyte Index => (sbyte)(Parent?.ModifiableRows.IndexOf(this) ?? throw new RhythmBaseException()); /// /// Gets or sets the rooms associated with the row. /// public RDSingleRoom Rooms { get; set; } /// /// Gets or sets a value indicating whether the row is hidden at the start. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool HideAtStart { get; set; } /// /// Gets or sets the initial player mode for the row. /// public PlayerType Player { get; set; } = PlayerType.P1; /// /// Gets the initial beat sound for the row. /// [JsonIgnore] public RDAudio Sound { get; set; } /// /// Gets or sets a value indicating whether the beats are muted. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool MuteBeats { get; set; } /// /// Gets or sets the row to mimic. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public sbyte RowToMimic { get; set; } /// /// Gets or sets the name of the pulse sound. /// public string PulseSound { get => Sound.Filename; set => Sound.Filename = value; } /// /// Gets or sets the volume of the pulse sound. /// public int PulseSoundVolume { get => Sound.Volume; set => Sound.Volume = value; } /// /// Gets or sets the pitch of the pulse sound. /// public int PulseSoundPitch { get => Sound.Pitch; set => Sound.Pitch = value; } /// /// Gets or sets the pan of the pulse sound. /// public int PulseSoundPan { get => Sound.Pan; set => Sound.Pan = value; } /// /// Gets or sets the offset of the pulse sound. /// [JsonConverter(typeof(MilliSecondConverter))] public TimeSpan PulseSoundOffset { get => Sound.Offset; set => Sound.Offset = value; } /// /// Initializes a new instance of the class. /// internal RowEventCollection() { Rooms = new RDSingleRoom(RDRoomIndex.Room1); Sound = new RDAudio(); RowToMimic = -1; } /// /// Adds an item to the row. /// /// The row event to add. public override void Add(BaseRowAction item) { if (item is not BaseBeat || (item is BaseBeat && ( ((item.Type is EventType.AddClassicBeat or EventType.AddFreeTimeBeat or EventType.PulseFreeTimeBeat or EventType.SetRowXs ) && RowType is RowType.Classic) || ((item.Type is EventType.AddOneshotBeat or EventType.SetOneshotWave ) && RowType is RowType.Oneshot) )) ) { item._parent?.Remove(item); item._parent = this; Parent?.Add(item); return; } throw new IllegalRowEventTypeException(item.Type, RowType); } /// /// Adds an item to the row safely. /// /// The row event to add. internal void AddSafely(BaseRowAction item) => base.Add(item); /// /// Removes an item from the row. /// /// The row event to remove. /// True if the item was successfully removed; otherwise, false. public override bool Remove(BaseRowAction item) => Parent?.Remove(item) ?? throw new RhythmBaseException(); /// /// Removes an item from the row safely. /// /// The row event to remove. /// True if the item was successfully removed; otherwise, false. internal bool RemoveSafely(BaseRowAction item) => base.Remove(item); private RowType _rowType; [JsonIgnore] internal RDLevel? Parent = null; } }