/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Copyright (c) 2017-2019 Swan & The Quaver Team . */ using System; using System.Collections.Generic; using System.Linq; //using MoonSharp.Interpreter; //using MoonSharp.Interpreter.Interop; using Quaver.API.Enums; using YamlDotNet.Serialization; namespace Quaver.API.Maps.Structures { /// /// HitObjects section of the .qua /// /*[MoonSharpUserData]*/ [Serializable] public class HitObjectInfo { /// /// The time in milliseconds when the HitObject is supposed to be hit. /// public int StartTime { get; /*[MoonSharpVisible(false)]*/ set; } /// /// The lane the HitObject falls in /// public int Lane { get; /*MoonSharpVisible(false)]*/ set; } /// /// The endtime of the HitObject (if greater than 0, it's considered a hold note.) /// public int EndTime { get; /*[MoonSharpVisible(false)]*/ set; } /// /// Bitwise combination of hit sounds for this object /// public HitSounds HitSound { get; /*[MoonSharpVisible(false)]*/ set; } /// /// Key sounds to play when this object is hit. /// /*[MoonSharpVisible(false)]*/ public List KeySounds { get; set; } = new List(); /// /// The layer in the editor that the object belongs to. /// public int EditorLayer { get; /*[MoonSharpVisible(false)]*/ set; } /// /// If the object is a long note. (EndTime > 0) /// [YamlIgnore] public bool IsLongNote => EndTime > 0; /// /// Returns if the object is allowed to be edited in lua scripts /// [YamlIgnore] public bool IsEditableInLuaScript { get; /*[MoonSharpVisible(false)]*/ set; } /// /// Gets the timing point this object is in range of. /// /// public TimingPointInfo GetTimingPoint(List timingPoints) { // Search through the entire list for the correct point for (var i = timingPoints.Count - 1; i >= 0; i--) { if (StartTime >= timingPoints[i].StartTime) return timingPoints[i]; } return timingPoints.First(); } /// /// /// /// public void SetStartTime(int time) { ThrowUneditableException(); StartTime = time; } /// /// /// public void SetEndTime(int time) { ThrowUneditableException(); EndTime = time; } /// /// /// public void SetLane(int lane) { ThrowUneditableException(); Lane = lane; } /// /// /// public void SetHitSounds(HitSounds hitsounds) { ThrowUneditableException(); HitSound = hitsounds; } /// /// /// private void ThrowUneditableException() { if (!IsEditableInLuaScript) throw new InvalidOperationException("Value is not allowed to be edited in lua scripts."); } /// /// By-value comparer, mostly auto-generated by Rider: KeySounds-related code is changed to by-value. /// private sealed class ByValueEqualityComparer : IEqualityComparer { public bool Equals(HitObjectInfo x, HitObjectInfo y) { if (ReferenceEquals(x, y)) return true; if (ReferenceEquals(x, null)) return false; if (ReferenceEquals(y, null)) return false; if (x.GetType() != y.GetType()) return false; return x.StartTime == y.StartTime && x.Lane == y.Lane && x.EndTime == y.EndTime && x.HitSound == y.HitSound && x.KeySounds.SequenceEqual(y.KeySounds, KeySoundInfo.ByValueComparer) && x.EditorLayer == y.EditorLayer; } public int GetHashCode(HitObjectInfo obj) { unchecked { var hashCode = obj.StartTime; hashCode = (hashCode * 397) ^ obj.Lane; hashCode = (hashCode * 397) ^ obj.EndTime; hashCode = (hashCode * 397) ^ (int) obj.HitSound; foreach (var keySound in obj.KeySounds) hashCode = (hashCode * 397) ^ KeySoundInfo.ByValueComparer.GetHashCode(keySound); hashCode = (hashCode * 397) ^ obj.EditorLayer; return hashCode; } } } public static IEqualityComparer ByValueComparer { get; } = new ByValueEqualityComparer(); } }