//Get the correct type of hitobject to put into the hitobject variable public GenericHitObject(string id, Beatmap map) { HitObjectType objecttype = HitObjectParser.GetHitObjectType(id); if(objecttype == HitObjectType.Circle) hitobject = new Circle(id); else if(objecttype == HitObjectType.Slider) { string slidertype = HitObjectParser.GetProperty(id, "slidertype"); if(slidertype == "L") hitobject = new LinearSlider(id, map); //Special behavior is needed for passthrough sliders else if(slidertype == "P") { //Treat the slider differently depending on the number of control points string[] sliderpoints = HitObjectParser.GetProperty(id, "controlpoints").Split('|'); if(sliderpoints.Length == 1) hitobject = new LinearSlider(id, map); else if(sliderpoints.Length == 2) hitobject = new PassthroughSlider(id, map); else hitobject = new BezierSlider(id, map); } else if(slidertype == "B") hitobject = new BezierSlider(id, map); else if(slidertype == "C") hitobject = new CatmullSlider(id, map); } else if(objecttype == HitObjectType.Spinner) hitobject = new Spinner(); else throw new ArgumentException("Error: id is invalid"); }
public CatmullSlider(string id, Beatmap amap) : base(id, amap) { Point initialcoord = new Point(); initialcoord.x = Int32.Parse(HitObjectParser.GetProperty(id, "x")); initialcoord.y = Int32.Parse(HitObjectParser.GetProperty(id, "y")); curve = new CatmullCurve(initialcoord, this.controlpoints); }
//Constructs a slider given an id //The beatmap given is the beatmap that the slider resides in //Used to make calculations related to timing protected GenericSlider(string tempid, Beatmap amap) { id = tempid; map = amap; //Checks that the hitobject given is actually a slider if(HitObjectParser.GetHitObjectType(id) != HitObjectType.Slider) throw new ArgumentException("Hitobject provided to slider class is not a slider"); //Gets the control points of the slider in a formatted array of Points controlpoints = FormatControlPoints(); }
public PassthroughSlider(string id, Beatmap amap) : base(id, amap) { if(controlpoints.Length != 2) throw new ArgumentException("Error: Passthrough slider does not have 2 control points\n" + "controlpoints.Length=" + controlpoints.Length); Point initialcoord = new Point(); initialcoord.x = Int32.Parse(HitObjectParser.GetProperty(id, "x")); initialcoord.y = Int32.Parse(HitObjectParser.GetProperty(id, "y")); double length = Math.Round(Double.Parse(HitObjectParser.GetProperty(id, "pixelLength"), CultureInfo.InvariantCulture), 4); curve = new CircleCurve(initialcoord, controlpoints[0], controlpoints[1], length); }
public PPCalc(int maxCombo, int amount300, int amount100, int amountKatu, int amount50, int amountMiss, Modifiers mods, Beatmap map) { this.maxCombo = maxCombo; this.amount300 = amount300; this.amount100 = amount100; this.amountKatu = amountKatu; this.amount50 = amount50; this.amountMiss = amountMiss; this.mods = mods; this.map = map; this.difficulty = new DiffCalc(map); ComputeTotalValue(); }
//Store the given beatmap and create a HitObjectParser from it public DiffCalc(Beatmap givenmap) { map = givenmap; //Checks that the beatmap given is the correct mode string mode = map.GetTag("general", "mode"); //No mode specified means standard (old maps have no mode) if(!(mode == "0" || mode == "2" || mode == null)) { throw new InvalidBeatmapException("Error: beatmap is not the correct mode (std or ctb)"); } //Make a parser from the map hitobjects = new HitObjectListParser(map); this.GetPositionsAndTimes(); }
//Uses the given list of control points to construct a list of curves //to account for red points public LinearSlider(string id, Beatmap amap) : base(id, amap) { //Get the initial hit point of the slider //Split into three lines for readibility Point initialcoord = new Point(); initialcoord.x = Int32.Parse(HitObjectParser.GetProperty(id, "x")); initialcoord.y = Int32.Parse(HitObjectParser.GetProperty(id, "y")); //List<Point> curvepoints = new List<Point>(); List<LinearCurve> accumulatedcurves = new List<LinearCurve>(); //Normal linear slider if(controlpoints.Length == 1) { accumulatedcurves.Add(new LinearCurve(initialcoord, controlpoints[0])); } else { List<Point> allcontrolpoints = new List<Point>(); //Add first point only if it's not repeated in the control points (old maps) if(initialcoord.IntX() != controlpoints[0].IntX() && initialcoord.IntY() != controlpoints[0].IntY()) allcontrolpoints.Add(initialcoord); allcontrolpoints.AddRange(controlpoints); Point[][] curvepoints = Dewlib.SplitPointList(allcontrolpoints.ToArray()); foreach(Point[] curve in curvepoints) { if(curve.Length > 2) { for(int i = 1; i < curve.Length; i++) { accumulatedcurves.Add(new LinearCurve(curve[i-1], curve[i])); } } else { accumulatedcurves.Add(new LinearCurve(curve[0], curve[1])); } } } curves = accumulatedcurves.ToArray(); }
//Uses the given list of control points to construct a list of bezier curves //to account for red points public BezierSlider(string id, Beatmap amap) : base(id, amap) { //Get the initial hit point of the slider //Split into three lines for readibility Point initialcoord = new Point(); initialcoord.x = Int32.Parse(HitObjectParser.GetProperty(id, "x")); initialcoord.y = Int32.Parse(HitObjectParser.GetProperty(id, "y")); List<BezierCurve> accumulatedcurves = new List<BezierCurve>(); List<Point> allcontrolpoints = new List<Point>(); allcontrolpoints.Add(initialcoord); allcontrolpoints.AddRange(controlpoints); Point[][] curvepoints = Dewlib.SplitPointList(allcontrolpoints.ToArray()); foreach(Point[] curve in curvepoints) { accumulatedcurves.Add(new BezierCurve(curve)); } curves = accumulatedcurves.ToArray(); }
public PatternParser(Beatmap givenmap, int[] positions, int[] times) { map = givenmap; hitpositions = positions; hittimes = times; }
public static void Main(string[] args) { Directory.SetCurrentDirectory(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)); DebugController debugger = new DebugController(); //Load in custom beatmaps if specified args = debugger.LoadCustom(args); //Display a message if no files are specified if(args.Length == 0) { Console.WriteLine("CTB Difficulty Analyzer"); Console.WriteLine("Just drag your beatmap (.osu file) onto this program to measure difficulty"); Console.WriteLine("Press any key to exit..."); } //Otherwise try to run the program, and catch and display any exceptions that arise else { Console.WriteLine("Calculating..."); SortedList<double, string> beatmaps = new SortedList<double, string>(); List<DiffCalc> calculators = new List<DiffCalc>(); Stopwatch timer = new Stopwatch(); try { int count = 0; foreach(string name in args) { timer.Start(); Beatmap map = new Beatmap(name); DiffCalc calc; try { calc = new DiffCalc(map); } catch(InvalidBeatmapException) { //Skip this beatmap if it's not a standard or ctb map, but only if //it was loaded through debug if(debugger.IsLoadCustom()) continue; else throw; } string title = calc.GetBeatmapTitle() + ": \t"; double difficulty = calc.GetDifficulty(); timer.Stop(); title += timer.ElapsedMilliseconds; beatmaps[difficulty] = title; calculators.Add(calc); timer.Reset(); count++; Console.Write(Math.Round((double)count * 100 / args.Length) + "%\r"); } Console.WriteLine("\n"); for(int i = beatmaps.Count - 1; i >= 0; i--) { string[] titleandtime = beatmaps.Values[i].Split('\t'); Console.WriteLine(titleandtime[0] + beatmaps.Keys[i]); Console.WriteLine("Calculation Time (ms): " + titleandtime[1] + "\n"); } debugger.WriteDebug(calculators.ToArray()); Console.WriteLine("\nDone."); } catch(Exception e) { Console.WriteLine(e); } finally { //Just in case the timer is still running timer.Stop(); } } Console.ReadKey(); }
// Gets the list of hitobjects from a beatmap object and stores it for later use public HitObjectListParser(Beatmap map) { this.hitobjects = map.GetSection("hitobjects"); }