public static HitObject ParseLine(Beatmap beatmap, string line) { string[] elements = line.Trim().Split(','); int type = Convert.ToInt32(elements[3]); // If elements have 5 size, it is a normal hit object. Parse it as required. if ((type & CIRCLE) != 0) { // Do a type check first. if (elements.Length == 6) { return(new HitCircle(beatmap, Convert.ToInt32(elements[0]), Convert.ToInt32(elements[1]), Convert.ToDouble(elements[2]), 0d, Convert.ToInt32(elements[3]), Convert.ToInt32(elements[4]), elements[5])); } else { MessageBoxUtils.showError("Type and element information does not match as a circle for line: " + line + ", aborting note processing."); return(null); } } // If elements have the size of 11, it is a slider. Parse it as required. else if ((type & SLIDER) != 0) { // Always check the length first. if (elements.Length < 8) { MessageBoxUtils.showError("Type and element information does not match as a slider for line: " + line + ", aborting note processing."); return(null); } else { // This requires some additional processing. double offset = Convert.ToDouble(elements[2]); TimingPoint point = SearchUtils.GetClosestTimingPoint(beatmap.TimingPoints, offset); if (point != null) { // We found the timing point, now it is time to construct the object. double pixelLength = Convert.ToDouble(elements[7]); double duration = pixelLength / (100.0 * beatmap.SliderMultiplier) * point.PointValue; string[] hitsoundStrings = elements.Length >= 9 && !string.IsNullOrWhiteSpace(elements[8]) ? elements[8].Split('|') : new string[0]; string extras = (elements.Length >= 10 ? elements[9] : "") + (elements.Length >= 11 ? "," + elements[10] : ""); List <int> edgeHitsounds = new List <int>(); for (int i = 0; i < hitsoundStrings.Length; i++) { edgeHitsounds.Add(Convert.ToInt32(hitsoundStrings[i])); } return(new HitSlider(beatmap, Convert.ToInt32(elements[0]), Convert.ToInt32(elements[1]), Convert.ToDouble(elements[2]), duration, type, Convert.ToInt32(elements[4]), string.Join(",", elements[5], elements[6], elements[7]), edgeHitsounds, extras)); } else { MessageBoxUtils.showError("Slider cannot be parsed, there was no relative timing point found at offset " + offset.ToString() + ", aborting note processing."); return(null); } } } else if ((type & SPINNER) != 0) { if (elements.Length == 7) { double duration = Convert.ToDouble(elements[5]) - Convert.ToDouble(elements[2]); return(new HitSpinner(beatmap, Convert.ToInt32(elements[0]), Convert.ToInt32(elements[1]), Convert.ToDouble(elements[2]), duration, type, Convert.ToInt32(elements[4]), elements[6])); } else { MessageBoxUtils.showError("Type and element information does not match as a spinner for line: " + line + ", aborting note processing."); return(null); } } else if ((type & MANIA_NOTE) != 0) { MessageBoxUtils.showError("Mania is not supported yet."); return(null); } else { MessageBoxUtils.showError("Unsupported element data found for line: " + line + ", aborting note " + "processing."); return(null); } }