public override void Reset() { base.Reset(); Clock.ProcessFrame(); Container approachContainer = new Container { Depth = float.MinValue, }; Add(approachContainer); const int count = 10; for (int i = 0; i < count; i++) { var h = new HitCircle { StartTime = Clock.CurrentTime + 1000 + i * 80, Position = new Vector2((i - count / 2) * 14), }; DrawableHitCircle d = new DrawableHitCircle(h) { Anchor = Anchor.Centre, Origin = Anchor.Centre, Depth = i, State = ArmedState.Hit, Judgement = new OsuJudgementInfo { Result = HitResult.Hit } }; approachContainer.Add(d.ApproachCircle.CreateProxy()); Add(d); } }
public DrawableHitCircle(HitCircle h) : base(h) { osuObject = h; Origin = Anchor.Centre; Position = osuObject.Position; Scale = new Vector2(osuObject.Scale); Children = new Drawable[] { glow = new GlowPiece { Colour = osuObject.Colour }, circle = new CirclePiece { Colour = osuObject.Colour, Hit = () => { if (Judgement.Result.HasValue) return false; ((PositionalJudgementInfo)Judgement).PositionOffset = Vector2.Zero; //todo: set to correct value UpdateJudgement(true); return true; }, }, number = new NumberPiece(), ring = new RingPiece(), flash = new FlashPiece(), explode = new ExplodePiece { Colour = osuObject.Colour, }, ApproachCircle = new ApproachCircle() { Colour = osuObject.Colour, } }; //may not be so correct Size = circle.DrawSize; }
public void TestQuickDeleteRemovesObject() { var addedObject = new HitCircle { StartTime = 1000 }; AddStep("add hitobject", () => EditorBeatmap.Add(addedObject)); AddStep("select added object", () => EditorBeatmap.SelectedHitObjects.Add(addedObject)); AddStep("move mouse to object", () => { var pos = blueprintContainer.ChildrenOfType <HitCirclePiece>().First().ScreenSpaceDrawQuad.Centre; InputManager.MoveMouseTo(pos); }); AddStep("hold shift", () => InputManager.PressKey(Key.ShiftLeft)); AddStep("right click", () => InputManager.Click(MouseButton.Right)); AddStep("release shift", () => InputManager.ReleaseKey(Key.ShiftLeft)); AddAssert("no hitobjects in beatmap", () => EditorBeatmap.HitObjects.Count == 0); }
public void TestBasicDeselect() { var addedObject = new HitCircle { StartTime = 100 }; AddStep("add hitobject", () => EditorBeatmap.Add(addedObject)); moveMouseToObject(() => addedObject); AddStep("left click", () => InputManager.Click(MouseButton.Left)); AddAssert("hitobject selected", () => EditorBeatmap.SelectedHitObjects.Single() == addedObject); AddStep("click away", () => { InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre); InputManager.Click(MouseButton.Left); }); AddAssert("selection lost", () => EditorBeatmap.SelectedHitObjects.Count == 0); }
public void HitObjectRemoveEvent() { var hitCircle = new HitCircle(); HitObject removedObject = null; EditorBeatmap editorBeatmap = null; AddStep("add beatmap", () => { Child = editorBeatmap = new EditorBeatmap(new OsuBeatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo, }, HitObjects = { hitCircle } }); editorBeatmap.HitObjectRemoved += h => removedObject = h; }); AddStep("remove hitobject", () => editorBeatmap.Remove(editorBeatmap.HitObjects.First())); AddAssert("received remove event", () => removedObject == hitCircle); }
public void TestBasicDeselect() { var addedObject = new HitCircle { StartTime = 100 }; AddStep("add hitobject", () => EditorBeatmap.Add(addedObject)); moveMouseToObject(() => addedObject); AddStep("left click", () => InputManager.Click(MouseButton.Left)); AddAssert("hitobject selected", () => EditorBeatmap.SelectedHitObjects.Single() == addedObject); AddStep("click away", () => { InputManager.MoveMouseTo(Editor.ChildrenOfType <TimelineArea>().Single().ScreenSpaceDrawQuad.TopLeft + Vector2.One); InputManager.Click(MouseButton.Left); }); AddAssert("selection lost", () => EditorBeatmap.SelectedHitObjects.Count == 0); }
private void Awake() { rectTransform = GetComponent <RectTransform>(); canvasGroup = GetComponent <CanvasGroup>(); canvasGroup.alpha = 0; HitCircle = (HitCircle)MusicPlayer.CurrentPlaying.HitObjects[PlayField.CurrentHitObject]; ar = MusicPlayer.CurrentPlaying.DifficultySection.ApproachRate; cs = MusicPlayer.CurrentPlaying.DifficultySection.CircleSize; hp = MusicPlayer.CurrentPlaying.DifficultySection.HPDrainRate; od = MusicPlayer.CurrentPlaying.DifficultySection.OverallDifficulty; spawnDelay = (int)PlayField.GameTimer.ElapsedMilliseconds - HitCircle.StartTime; transform.position = Camera.main.ScreenToWorldPoint ( new Vector3 ( x: HitCircle.Position.X * Screen.width / 512, y: HitCircle.Position.Y * Screen.height / 384 ) ); transform.position = new Vector3(transform.position.x, transform.position.y, 0); if (ar < 5) { fadeIn = (int)(800 + 400 * (5 - ar) / 5); preempt = (int)(1200 + 600 * (5 - ar) / 5); } else if (ar == 5) { fadeIn = 800; preempt = 1200; } else { fadeIn = (int)(800 - 500 * (ar - 5) / 5); preempt = (int)(1200 - 750 * (ar - 5) / 5); } elapsedTimeSinceSpawn = spawnDelay; originalApproachCircleScale = ApproachCircle.transform.localScale; // SetCircleSize(cs); // somehow if this line is in Awake the size of the circle will be the square of the intended size and I have no f*****g idea why that happens // ApproachCircle.transform.localScale *= 2; }
public void TestMultipleHitObjectUpdate() { var updatedObjects = new List <HitObject>(); var allHitObjects = new List <HitObject>(); EditorBeatmap editorBeatmap = null; AddStep("add beatmap", () => { updatedObjects.Clear(); Child = editorBeatmap = new EditorBeatmap(new OsuBeatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo, }, }); for (int i = 0; i < 10; i++) { var h = new HitCircle(); editorBeatmap.Add(h); allHitObjects.Add(h); } }); AddStep("change all start times", () => { editorBeatmap.HitObjectUpdated += h => updatedObjects.Add(h); for (int i = 0; i < 10; i++) { allHitObjects[i].StartTime += 10; } }); // Distinct ensures that all hitobjects have been updated once, debounce is tested below. AddAssert("all hitobjects updated", () => updatedObjects.Distinct().Count() == 10); }
public void TestAddObjectAndUndo() { HitObject addedObject = null; HitObject removedObject = null; HitObject expectedObject = null; AddStep("bind removal", () => { editorBeatmap.HitObjectAdded += h => addedObject = h; editorBeatmap.HitObjectRemoved += h => removedObject = h; }); AddStep("add hitobject", () => editorBeatmap.Add(expectedObject = new HitCircle { StartTime = 1000 })); AddAssert("hitobject added", () => addedObject == expectedObject); AddAssert("unsaved changes", () => Editor.HasUnsavedChanges); addUndoSteps(); AddAssert("hitobject removed", () => removedObject == expectedObject); AddAssert("no unsaved changes", () => !Editor.HasUnsavedChanges); }
private TestDrawableHitCircle createSingle(float circleSize, bool auto, double timeOffset, Vector2?positionOffset, double hitOffset = 0) { positionOffset ??= Vector2.Zero; var circle = new HitCircle { StartTime = Time.Current + 1000 + timeOffset, Position = OsuPlayfield.BASE_SIZE / 4 + positionOffset.Value, }; circle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); var drawable = CreateDrawableHitCircle(circle, auto, hitOffset); foreach (var mod in SelectedMods.Value.OfType <IApplicableToDrawableHitObject>()) { mod.ApplyToDrawableHitObject(drawable); } return(drawable); }
public void TestRemovedHitObjectStartTimeChangeEvent() { var hitCircle = new HitCircle(); var editorBeatmap = new EditorBeatmap(new OsuBeatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo, }, HitObjects = { hitCircle } }); HitObject changedObject = null; editorBeatmap.HitObjectUpdated += h => changedObject = h; editorBeatmap.Remove(hitCircle); Assert.That(changedObject, Is.Null); hitCircle.StartTime = 1000; Assert.That(changedObject, Is.Null); }
public void TestHitObjectAddEvent() { var hitCircle = new HitCircle(); HitObject addedObject = null; EditorBeatmap editorBeatmap = null; AddStep("add beatmap", () => { Child = editorBeatmap = new EditorBeatmap(new OsuBeatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo, }, }); editorBeatmap.HitObjectAdded += h => addedObject = h; }); AddStep("add hitobject", () => editorBeatmap.Add(hitCircle)); AddAssert("received add event", () => addedObject == hitCircle); }
private Drawable testSingle(float circleSize, bool auto = false, double timeOffset = 0, Vector2?positionOffset = null) { positionOffset ??= Vector2.Zero; var circle = new HitCircle { StartTime = Time.Current + 1000 + timeOffset, Position = positionOffset.Value, }; circle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); var drawable = CreateDrawableHitCircle(circle, auto); foreach (var mod in SelectedMods.Value.OfType <IApplicableToDrawableHitObjects>()) { mod.ApplyToDrawableHitObjects(new[] { drawable }); } return(drawable); }
internal override void Update() { base.Update(); List <HitCircle> timelineCircles = new List <HitCircle>(); List <Slider> timelineSliders = new List <Slider>(); editor.timelineManager.SpriteList.ForEach(delegate(pDrawable p) { HitCircle c = p.Tag as HitCircle; Slider sl; if (c != null) { timelineCircles.Add(c); } else if ((sl = p.Tag as Slider) != null) { timelineSliders.Add(sl); } }); foreach (HitObject h in timelineCircles) { if (h.Whistle || h.Clap) { h.SetColour(new Color(67, 142, 172)); } else { h.SetColour(new Color(235, 69, 44)); } } foreach (Slider sl in timelineSliders) { sl.SetColour(new Color(252, 184, 6)); } }
public static void DrawHitCircle(SKCanvas canvas, int gameTime, HitCircle circle) { // t0 => circle is starting to fade in // t1 => circle is now fully visible // t2 => circle is starting to fade out // t3 => circle is no longer visible double t0 = circle.StartTime - circle.TimePreempt; double t1 = t0 + circle.TimeFadeIn; double t2 = circle.StartTime; double t3 = t2 + 250; // progress 0 -> 1 double fadeInProgress = (gameTime - t0) / (t1 - t0); double fadeOutProgress = (gameTime - t2) / (t3 - t2); double transparency = (gameTime < t0) ? 0 : (gameTime < t1) ? 255 * fadeInProgress : (gameTime < t2) ? 255 : (gameTime < t3) ? 255 * (1 - fadeOutProgress) : 0; double scale = (gameTime < t2) ? 1.0 : 1.0 + 0.3 * Math.Sqrt(Math.Sin(Math.PI * fadeOutProgress / 2.0)); DrawCircleImage(canvas, circle.StackedPosition, (float)(scale * circle.Radius) / 2.0f, HitCircleBitmap, (byte)transparency); DrawCircleImage(canvas, circle.StackedPosition, (float)(scale * circle.Radius) / 2.0f, HitCircleOverlayBitmap, (byte)transparency); //var circleStyle = new SKPaint //{ // IsAntialias = true, // IsStroke = true, // Color = SKColor.FromHsv(0, 0, 80, (byte)transparency), // StrokeWidth = 1 //}; //canvas.DrawCircle(circle.StackedPosition.X, circle.StackedPosition.Y, (float)(scale * circle.Radius) / 2.0f, circleStyle); }
public void TestInitialHitObjectStartTimeChangeEvent() { var hitCircle = new HitCircle(); HitObject changedObject = null; AddStep("add beatmap", () => { EditorBeatmap editorBeatmap; Child = editorBeatmap = new EditorBeatmap(new OsuBeatmap { BeatmapInfo = { Ruleset = new OsuRuleset().RulesetInfo, }, HitObjects = { hitCircle } }); editorBeatmap.HitObjectUpdated += h => changedObject = h; }); AddStep("change start time", () => hitCircle.StartTime = 1000); AddAssert("received change event", () => changedObject == hitCircle); }
public new void SetUp() { base.SetUp(); Schedule(() => { hitCircle = new HitCircle { Position = new Vector2(100, 100), StartTime = Time.Current + 500 }; hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); Child = new SkinProvidingContainer(new DefaultSkin()) { RelativeSizeAxes = Axes.Both, Child = drawableHitCircle = new DrawableHitCircle(hitCircle) { Size = new Vector2(100) } }; }); }
public void TestHitCircleAnimationDisable() { HitCircle hitCircle = null; DrawableHitCircle drawableHitCircle = null; AddStep("retrieve first hit circle", () => hitCircle = getHitCircle(0)); toggleAnimations(true); seekSmoothlyTo(() => hitCircle.StartTime + 10); AddStep("retrieve drawable", () => drawableHitCircle = (DrawableHitCircle)getDrawableObjectFor(hitCircle)); assertFutureTransforms(() => drawableHitCircle.CirclePiece, true); AddStep("retrieve second hit circle", () => hitCircle = getHitCircle(1)); toggleAnimations(false); seekSmoothlyTo(() => hitCircle.StartTime + 10); AddStep("retrieve drawable", () => drawableHitCircle = (DrawableHitCircle)getDrawableObjectFor(hitCircle)); assertFutureTransforms(() => drawableHitCircle.CirclePiece, false); AddAssert("hit circle has longer fade-out applied", () => { var alphaTransform = drawableHitCircle.Transforms.Last(t => t.TargetMember == nameof(Alpha)); return(alphaTransform.EndTime - alphaTransform.StartTime == DrawableOsuEditorRuleset.EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION); }); }
private HitCircle prepareObject(HitCircle circle) { circle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); return(circle); }
public DrawableHitCircle([CanBeNull] HitCircle h = null) : base(h) { }
protected override TestDrawableHitCircle CreateDrawableHitCircle(HitCircle circle, bool auto, double hitOffset = 0) { circle.ComboIndexBindable.BindTo(comboIndex); circle.IndexInCurrentComboBindable.BindTo(comboIndex); return(base.CreateDrawableHitCircle(circle, auto, hitOffset)); }
public TestDrawableHitCircle(HitCircle h, bool auto) : base(h) { this.auto = auto; }
public Issue Create(HitCircle circle) => new Issue(circle, this);
public DrawableSliderHead(Slider slider, HitCircle h) : base(h) { this.slider = slider; }
public static void Create(BlobBuilder builder, HitCircle src, ref BlobPtr <Collider> dest, ColliderType type = ColliderType.Circle) { ref var ptr = ref UnsafeUtility.As <BlobPtr <Collider>, BlobPtr <CircleCollider> >(ref dest);
protected virtual TestDrawableHitCircle CreateDrawableHitCircle(HitCircle circle, bool auto) => new TestDrawableHitCircle(circle, auto) { Anchor = Anchor.Centre, Depth = depthIndex++ };
public override HitObject Parse(string text) { string[] split = text.Split(','); var type = (OsuHitObject.HitObjectType)int.Parse(split[3]); bool combo = type.HasFlag(OsuHitObject.HitObjectType.NewCombo); type &= (OsuHitObject.HitObjectType)0xF; type &= ~OsuHitObject.HitObjectType.NewCombo; OsuHitObject result; switch (type) { case OsuHitObject.HitObjectType.Circle: result = new HitCircle(); break; case OsuHitObject.HitObjectType.Slider: Slider s = new Slider(); CurveTypes curveType = CurveTypes.Catmull; int repeatCount = 0; double length = 0; List<Vector2> points = new List<Vector2>(); points.Add(new Vector2(int.Parse(split[0]), int.Parse(split[1]))); string[] pointsplit = split[5].Split('|'); for (int i = 0; i < pointsplit.Length; i++) { if (pointsplit[i].Length == 1) { switch (pointsplit[i]) { case @"C": curveType = CurveTypes.Catmull; break; case @"B": curveType = CurveTypes.Bezier; break; case @"L": curveType = CurveTypes.Linear; break; case @"P": curveType = CurveTypes.PerfectCurve; break; } continue; } string[] temp = pointsplit[i].Split(':'); Vector2 v = new Vector2( (int)Convert.ToDouble(temp[0], CultureInfo.InvariantCulture), (int)Convert.ToDouble(temp[1], CultureInfo.InvariantCulture) ); points.Add(v); } repeatCount = Convert.ToInt32(split[6], CultureInfo.InvariantCulture); if (repeatCount > 9000) { throw new ArgumentOutOfRangeException("wacky man"); } if (split.Length > 7) length = Convert.ToDouble(split[7], CultureInfo.InvariantCulture); s.RepeatCount = repeatCount; s.Curve = new SliderCurve { ControlPoints = points, Length = length, CurveType = curveType }; s.Curve.Calculate(); result = s; break; case OsuHitObject.HitObjectType.Spinner: result = new Spinner(); break; default: //throw new InvalidOperationException($@"Unknown hit object type {type}"); return null; } result.Position = new Vector2(int.Parse(split[0]), int.Parse(split[1])); result.StartTime = double.Parse(split[2]); result.Sample = new HitSampleInfo { Type = (SampleType)int.Parse(split[4]), Set = SampleSet.Soft, }; result.NewCombo = combo; // TODO: "addition" field return result; }
public void ParseBeatmap(string beatmap, string path) { var bm = beatmap.Split("\n"); var hitObjects = false; var general = false; var difficulty = false; var color = false; var timingPonts = false; var events = false; var hitObjColIndex = 0; var hitObjectColor = SkinManager.SkinColors[0]; foreach (var fln in bm) { var line = fln.Trim(); if (line.Equals("") || line.Equals(" ")) { // We've finished reading! hitObjects = false; general = false; difficulty = false; color = false; timingPonts = false; events = false; continue; } if (line.StartsWith("osu file format v")) { var l = line.Split("osu file format v"); } if (line.StartsWith("[HitObjects]")) { hitObjects = true; continue; } if (line.StartsWith("[General]")) { general = true; continue; } if (line.StartsWith("[Difficulty]")) { difficulty = true; continue; } if (line.StartsWith("[Colours]")) { color = true; continue; } if (line.StartsWith("[TimingPoints]")) { timingPonts = true; continue; } if (line.StartsWith("[Events]")) { events = true; continue; } if (general) { if (line.StartsWith("AudioLeadIn:")) { General.AudioLeadIn = int.Parse(line.Split("AudioLeadIn:")[1].Trim()); } if (line.StartsWith("AudioFilename:")) { General.AudioFilename = line.Split("AudioFilename:")[1].Trim(); } } if (difficulty) { if (line.StartsWith("CircleSize:")) { Difficulty.CircleSize = double.Parse(line.Split("CircleSize:")[1].Trim()); } if (line.StartsWith("ApproachRate:")) { Difficulty.ApproachRate = double.Parse(line.Split("ApproachRate:")[1].Trim()); } if (line.StartsWith("OverallDifficulty:")) { Difficulty.OverallDifficulty = double.Parse(line.Split("OverallDifficulty:")[1].Trim()); } if (line.StartsWith("SliderMultiplier:")) { Difficulty.SliderMultiplier = double.Parse(line.Split("SliderMultiplier:")[1].Trim()); } } if (color) { var l = line.Split(":").Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList(); var rgb = l[1]; var col = rgb.Split(","); Colors.Add(new Color4(byte.Parse(col[0]), byte.Parse(col[1]), byte.Parse(col[2]), Byte.MaxValue)); } if (timingPonts) { var l = line.Split(","); var timingPoint = new TimingPoint { Offset = double.Parse(l[0].Trim()), MsPerBeat = double.Parse(l[1].Trim()), Meter = int.Parse(l[2].Trim()), SampleSet = int.Parse(l[3].Trim()), SampleIndex = int.Parse(l[4].Trim()), Volume = int.Parse(l[5].Trim()), Inherited = l[6].Trim() == "0", // this is reversed for some f*****g reason. FINALLY!! KiaiMode = l[7].Trim() == "1" }; timingPoint.BPM = 60000d / timingPoint.MsPerBeat; if (timingPoint.Inherited) { timingPoint.SpeedMultiplier = -100 * _lastBpm / timingPoint.MsPerBeat; } else { timingPoint.SpeedMultiplier = timingPoint.BPM; _lastBpm = timingPoint.SpeedMultiplier; } timingPoint.Velocity = Difficulty.SliderMultiplier * timingPoint.SpeedMultiplier / 600f; TimingPoints.Add(timingPoint); } if (events) { var l = line.Split(","); if (l[0].StartsWith("//")) { continue; } switch (l[0]) { case "0": var backgroundPath = Path.GetDirectoryName(path) + "/" + l[2] // Remove Quotes .Remove(0, 1) .Remove(l[2].Length - 2, 1); if (!File.Exists(backgroundPath)) { continue; } using (var fs = File.OpenRead(backgroundPath)) { Background = Texture.FromStream(fs); } break; default: Console.WriteLine("Event [{0}] not implemented!", l[0]); break; } } if (hitObjects) { var l = line.Split(","); var x = double.Parse(l[0]); var y = double.Parse(l[1]); var timing = int.Parse(l[2]); var hitObjectType = Enum.Parse <HitObjectType>(l[3]); if ((hitObjectType & HitObjectType.NewCombo) != 0) { hitObjColIndex++; if (hitObjColIndex >= Colors.Count) { hitObjColIndex = 0; } if (Colors.Count == 0) { Colors.AddRange(SkinManager.SkinColors); } hitObjectColor = Colors[hitObjColIndex]; } if ((hitObjectType & HitObjectType.Circle) != 0) { HitObject circle = new HitCircle(this, new Vector2((float)x, (float)y)); circle.BeginTime = timing; circle.HitObjectColour = hitObjectColor; HitObjects.Add(circle); } if ((hitObjectType & HitObjectType.Slider) != 0) { var sliderInfo = l[5].Split("|"); var sliderType = sliderInfo[0] switch { "L" => PathType.Linear, "P" => PathType.PerfectCurve, "B" => PathType.Bezier, "C" => PathType.Catmull, _ => PathType.Linear }; var curvePoints = new List <Vector2> { new Vector2((float)x, (float)y) }; foreach (var s in sliderInfo) { if (!s.Contains(":")) { continue; } var cp = s.Split(":").Select(double.Parse).ToList(); x = cp[0]; y = cp[1]; var curvePoint = new Vector2((float)x, (float)y); curvePoints.Add(curvePoint); } var pixelLength = double.Parse(l[7].Trim()); var repeats = int.Parse(l[6].Trim()); HitObject slider = new HitSlider( this, sliderType, curvePoints, pixelLength, repeats); slider.BeginTime = timing; slider.TimingPoint = TimingPoints.FirstOrDefault(s => s.Offset >= timing); slider.HitObjectColour = hitObjectColor; HitObjects.Add(slider); } } } // Sort by Time HitObjects.Sort((a, b) => (int)(a.BeginTime - b.BeginTime)); for (var i = 0; i < HitObjects.Count; i++) { var obj = HitObjects[i]; obj.Depth = i; } }
public TestDrawableHitCircle(HitCircle h, bool auto, double hitOffset) : base(h) { this.auto = auto; this.hitOffset = hitOffset; }
protected virtual TestDrawableHitCircle CreateDrawableHitCircle(HitCircle circle, bool auto, double hitOffset = 0) => new TestDrawableHitCircle(circle, auto, hitOffset) { Depth = depthIndex++ };
private static void ParseHitObjects(string line) { string[] tokens = line.Split(','); Vector2 position = new Vector2(ParseHelper.ToFloat(tokens[0]), ParseHelper.ToFloat(tokens[1])); int startTime = Convert.ToInt32(tokens[2]); HitObjectType type = (HitObjectType)int.Parse(tokens[3]); int comboOffset = (int)(type & HitObjectType.ComboOffset) >> 4; type &= ~HitObjectType.ComboOffset; bool isNewCombo = type.HasFlag(HitObjectType.NewCombo); type &= ~HitObjectType.NewCombo; HitSoundType hitSound = (HitSoundType)Convert.ToInt32(tokens[4]); HitObject hitObject = null; string[] extrasSplit = tokens.Last().Split(':'); int extrasOffset = type.HasFlag(HitObjectType.Hold) ? 1 : 0; Extras extras = tokens.Last().Contains(":") ? new Extras { SampleSet = (SampleSet)Convert.ToInt32(extrasSplit[0 + extrasOffset]), AdditionSet = (SampleSet)Convert.ToInt32(extrasSplit[1 + extrasOffset]), CustomIndex = extrasSplit.Length > 2 + extrasOffset ? Convert.ToInt32(extrasSplit[2 + extrasOffset]) : 0, Volume = extrasSplit.Length > 3 + extrasOffset ? Convert.ToInt32(extrasSplit[3 + extrasOffset]) : 0, SampleFileName = extrasSplit.Length > 4 + extrasOffset ? extrasSplit[4 + extrasOffset] : string.Empty } : new Extras(); switch (type) { case HitObjectType.Circle: { if (Beatmap.GeneralSection.Mode == Ruleset.Standard) { hitObject = new HitCircle(position, startTime, startTime, hitSound, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Taiko) { hitObject = new TaikoHit(position, startTime, startTime, hitSound, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Fruits) { hitObject = new CatchFruit(position, startTime, startTime, hitSound, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Mania) { hitObject = new ManiaNote(position, startTime, startTime, hitSound, extras, isNewCombo, comboOffset); } } break; case HitObjectType.Slider: { CurveType curveType = ParseHelper.GetCurveType(tokens[5].Split('|')[0][0]); List <Vector2> sliderPoints = ParseHelper.GetSliderPoints(tokens[5].Split('|')); int repeats = Convert.ToInt32(tokens[6]); double pixelLength = ParseHelper.ToDouble(tokens[7]); int endTime = MathHelper.CalculateEndTime(Beatmap, startTime, repeats, pixelLength); List <HitSoundType> edgeHitSounds = null; if (tokens.Length > 8 && tokens[8].Length > 0) { edgeHitSounds = new List <HitSoundType>(); edgeHitSounds = Array.ConvertAll(tokens[8].Split('|'), s => (HitSoundType)Convert.ToInt32(s)).ToList(); } List <Tuple <SampleSet, SampleSet> > edgeAdditions = null; if (tokens.Length > 9 && tokens[9].Length > 0) { edgeAdditions = new List <Tuple <SampleSet, SampleSet> >(); foreach (var s in tokens[9].Split('|')) { edgeAdditions.Add(new Tuple <SampleSet, SampleSet>((SampleSet)Convert.ToInt32(s.Split(':').First()), (SampleSet)Convert.ToInt32(s.Split(':').Last()))); } } if (Beatmap.GeneralSection.Mode == Ruleset.Standard) { hitObject = new Slider(position, startTime, endTime, hitSound, curveType, sliderPoints, repeats, pixelLength, isNewCombo, comboOffset, edgeHitSounds, edgeAdditions, extras); } else if (Beatmap.GeneralSection.Mode == Ruleset.Taiko) { hitObject = new TaikoDrumroll(position, startTime, endTime, hitSound, curveType, sliderPoints, repeats, pixelLength, edgeHitSounds, edgeAdditions, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Fruits) { hitObject = new CatchJuiceStream(position, startTime, endTime, hitSound, curveType, sliderPoints, repeats, pixelLength, isNewCombo, comboOffset, edgeHitSounds, edgeAdditions, extras); } else if (Beatmap.GeneralSection.Mode == Ruleset.Mania) { hitObject = new ManiaHoldNote(position, startTime, endTime, hitSound, extras, isNewCombo, comboOffset); } } break; case HitObjectType.Spinner: { int endTime = Convert.ToInt32(tokens[5].Trim()); if (Beatmap.GeneralSection.Mode == Ruleset.Standard) { hitObject = new Spinner(position, startTime, endTime, hitSound, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Taiko) { hitObject = new TaikoSpinner(position, startTime, endTime, hitSound, extras, isNewCombo, comboOffset); } else if (Beatmap.GeneralSection.Mode == Ruleset.Fruits) { hitObject = new CatchBananaRain(position, startTime, endTime, hitSound, extras, isNewCombo, comboOffset); } } break; case HitObjectType.Hold: { string[] additions = tokens[5].Split(':'); int endTime = Convert.ToInt32(additions[0].Trim()); hitObject = new ManiaHoldNote(position, startTime, endTime, hitSound, extras, isNewCombo, comboOffset); } break; } Beatmap.HitObjects.Add(hitObject); }
public DrawableSliderTail(HitCircle hitCircle) : base(hitCircle) { AlwaysPresent = true; RelativeSizeAxes = Axes.Both; }