public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new BeatmapProcessor(beatmap);
public PassThroughWorkingBeatmap(IBeatmap beatmap) : base(beatmap.BeatmapInfo, null) { this.beatmap = beatmap; }
public OsuBeatmapConverter(IBeatmap beatmap) : base(beatmap) { }
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, IBeatmap originalBeatmap) : base(random, hitObject, beatmap, new Pattern(), originalBeatmap) { endTime = (HitObject as IHasEndTime)?.EndTime ?? 0; }
/// <summary> /// Create an instance which provides the <see cref="IBeatmap"/> when requested. /// </summary> /// <param name="beatmap">The beatmap.</param> /// <param name="storyboard">An optional storyboard.</param> public TestWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) : base(beatmap.BeatmapInfo, null) { this.beatmap = beatmap; this.storyboard = storyboard; }
public static List <SentakkiHitObject> CreateTapFromTicks(HitObject original, int path, IBeatmap beatmap, Random rng) { var curve = original as IHasCurve; double spanDuration = curve.Duration / (curve.RepeatCount + 1); bool isRepeatSpam = spanDuration < 75 && curve.RepeatCount > 0; List <SentakkiHitObject> hitObjects = new List <SentakkiHitObject>(); if (isRepeatSpam) { return(hitObjects); } var difficulty = beatmap.BeatmapInfo.BaseDifficulty; var controlPointInfo = beatmap.ControlPointInfo; TimingControlPoint timingPoint = controlPointInfo.TimingPointAt(original.StartTime); DifficultyControlPoint difficultyPoint = controlPointInfo.DifficultyPointAt(original.StartTime); double scoringDistance = 100 * difficulty.SliderMultiplier * difficultyPoint.SpeedMultiplier; var velocity = scoringDistance / timingPoint.BeatLength; var tickDistance = scoringDistance / difficulty.SliderTickRate; double legacyLastTickOffset = (original as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0; foreach (var e in SliderEventGenerator.Generate(original.StartTime, spanDuration, velocity, tickDistance, curve.Path.Distance, curve.RepeatCount + 1, legacyLastTickOffset)) { int newPath = path; while (newPath == path) { newPath = rng.Next(0, 8); } switch (e.Type) { case SliderEventType.Tick: case SliderEventType.Repeat: hitObjects.Add(new Tap { NoteColor = Color4.Orange, Angle = newPath.GetAngleFromPath(), Samples = getTickSamples(original.Samples), StartTime = e.Time, EndPosition = SentakkiExtensions.GetPosition(SentakkiPlayfield.INTERSECTDISTANCE, newPath), Position = SentakkiExtensions.GetPosition(SentakkiPlayfield.NOTESTARTDISTANCE, newPath), }); break; } } return(hitObjects); }
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
public DrawableDivaRuleset(DivaRuleset ruleset, IBeatmap beatmap, IReadOnlyList <Mod> mods = null) : base(ruleset, beatmap, mods) { }
public DrawableRushRuleset(RushRuleset ruleset, IBeatmap beatmap, IReadOnlyList <Mod> mods = null) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Left; TimeRange.Value = 800; }
protected override IEnumerable <DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty <DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap) => Array.Empty <Skill>();
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate) { return(new DifficultyAttributes(mods, skills, 0)); }
protected override IEnumerable <TaikoHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap, CancellationToken cancellationToken) { // Old osu! used hit sounding to determine various hit type information IList <HitSampleInfo> samples = obj.Samples; switch (obj) { case IHasDistance distanceData: { if (shouldConvertSliderToHits(obj, beatmap, distanceData, out int taikoDuration, out double tickSpacing)) { IList <IList <HitSampleInfo> > allSamples = obj is IHasPathWithRepeats curveData ? curveData.NodeSamples : new List <IList <HitSampleInfo> >(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { IList <HitSampleInfo> currentSamples = allSamples[i]; yield return(new Hit { StartTime = j, Samples = currentSamples, }); i = (i + 1) % allSamples.Count; if (Precision.AlmostEquals(0, tickSpacing)) { break; } } }
public TaikoBeatmapConverter(IBeatmap beatmap, Ruleset ruleset) : base(beatmap, ruleset) { isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo); }
protected override int GetMaxCombo(IBeatmap beatmap) => beatmap.HitObjects.Count + beatmap.HitObjects.OfType <Slider>().Sum(s => s.NestedHitObjects.Count - 1);
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList <Mod> mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
protected override Dictionary <HitResult, int> GenerateHitResults(double accuracy, IBeatmap beatmap, int countMiss, int?countMeh, int?countGood) { int countGreat; var totalResultCount = beatmap.HitObjects.Count; if (countMeh != null || countGood != null) { countGreat = totalResultCount - (countGood ?? 0) - (countMeh ?? 0) - countMiss; } else { // Let Great=6, Good=2, Meh=1, Miss=0. The total should be this. var targetTotal = (int)Math.Round(accuracy * totalResultCount * 6); // Start by assuming every non miss is a meh // This is how much increase is needed by greats and goods var delta = targetTotal - (totalResultCount - countMiss); // Each great increases total by 5 (great-meh=5) countGreat = delta / 5; // Each good increases total by 1 (good-meh=1). Covers remaining difference. countGood = delta % 5; // Mehs are left over. Could be negative if impossible value of amountMiss chosen countMeh = totalResultCount - countGreat - countGood - countMiss; } return(new Dictionary <HitResult, int> { { HitResult.Great, countGreat }, { HitResult.Good, countGood ?? 0 }, { HitResult.Meh, countMeh ?? 0 }, { HitResult.Miss, countMiss } }); }
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this);
public static List <SentakkiHitObject> CreateHoldNote(HitObject original, int path, IBeatmap beatmap, Random rng, bool experimental) { var curveData = original as IHasCurve; List <SentakkiHitObject> notes = new List <SentakkiHitObject>(); bool twin = curveData.NodeSamples.Any(s => s.Any(s => s.Name == HitSampleInfo.HIT_CLAP)); notes.Add(new Hold { NoteColor = Color4.Crimson, Angle = path.GetAngleFromPath(), NodeSamples = curveData.NodeSamples, StartTime = original.StartTime, EndTime = original.GetEndTime(), EndPosition = SentakkiExtensions.GetPosition(SentakkiPlayfield.INTERSECTDISTANCE, path), Position = SentakkiExtensions.GetPosition(SentakkiPlayfield.NOTESTARTDISTANCE, path), }); if (experimental) { if (twin) { int newPath = path; while (path == newPath) { newPath = rng.Next(0, 8); } notes.Add(new Hold { NoteColor = Color4.Crimson, Angle = newPath.GetAngleFromPath(), NodeSamples = curveData.NodeSamples, StartTime = original.StartTime, EndTime = original.GetEndTime(), EndPosition = SentakkiExtensions.GetPosition(SentakkiPlayfield.INTERSECTDISTANCE, newPath), Position = SentakkiExtensions.GetPosition(SentakkiPlayfield.NOTESTARTDISTANCE, newPath), }); } else { var taps = CreateTapFromTicks(original, path, beatmap, rng); if (taps.Any()) { notes.AddRange(taps); } } } return(notes); }
public override ISkin CreateLegacySkinProvider(ISkinSource source, IBeatmap beatmap) => new ManiaLegacySkinTransformer(source, beatmap);
public DrawableOsuEditRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList <Mod> mods) : base(ruleset, beatmap, mods) { }
public TestWorkingBeatmap(BeatmapInfo skinBeatmapInfo, IResourceStore <byte[]> resourceStore, IBeatmap beatmap, Storyboard storyboard, IFrameBasedClock referenceClock, AudioManager audio, double length = 60000) : base(beatmap, storyboard, referenceClock, audio, length) { this.skinBeatmapInfo = skinBeatmapInfo; this.resourceStore = resourceStore; }
public DrawableEmptyFreeformRuleset(EmptyFreeformRuleset ruleset, IBeatmap beatmap, IReadOnlyList <Mod> mods = null) : base(ruleset, beatmap, mods) { }
protected sealed override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new TestWorkingBeatmap(beatmapInfo, beatmapSkinResourceStore, beatmap, storyboard, Clock, Audio);
protected abstract DrawableRuleset <TObject> CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList <Mod> mods = null);
public DummyConversionBeatmap(IBeatmap beatmap) : base(beatmap.BeatmapInfo, null) { this.beatmap = beatmap; }
public void Patch(byte[] currentState, byte[] newState) { // Diff the beatmaps var result = new Differ().CreateLineDiffs(readString(currentState), readString(newState), true, false); // Find the index of [HitObject] sections. Lines changed prior to this index are ignored. int oldHitObjectsIndex = Array.IndexOf(result.PiecesOld, "[HitObjects]"); int newHitObjectsIndex = Array.IndexOf(result.PiecesNew, "[HitObjects]"); var toRemove = new List <int>(); var toAdd = new List <int>(); foreach (var block in result.DiffBlocks) { // Removed hitobjects for (int i = 0; i < block.DeleteCountA; i++) { int hoIndex = block.DeleteStartA + i - oldHitObjectsIndex - 1; if (hoIndex < 0) { continue; } toRemove.Add(hoIndex); } // Added hitobjects for (int i = 0; i < block.InsertCountB; i++) { int hoIndex = block.InsertStartB + i - newHitObjectsIndex - 1; if (hoIndex < 0) { continue; } toAdd.Add(hoIndex); } } // Sort the indices to ensure that removal + insertion indices don't get jumbled up post-removal or post-insertion. // This isn't strictly required, but the differ makes no guarantees about order. toRemove.Sort(); toAdd.Sort(); // Apply the changes. for (int i = toRemove.Count - 1; i >= 0; i--) { editorBeatmap.RemoveAt(toRemove[i]); } if (toAdd.Count > 0) { IBeatmap newBeatmap = readBeatmap(newState); foreach (var i in toAdd) { editorBeatmap.Insert(i, newBeatmap.HitObjects[i]); } } }
public override void ApplyBeatmap(IBeatmap beatmap) { base.ApplyBeatmap(beatmap); beatmapApplied = true; }
protected override IEnumerable <OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap) { var curveData = original as IHasCurve; var endTimeData = original as IHasEndTime; var positionData = original as IHasPosition; var comboData = original as IHasCombo; var legacyOffset = original as IHasLegacyLastTickOffset; if (curveData != null) { yield return(new Slider { StartTime = original.StartTime, Samples = original.Samples, Path = curveData.Path, NodeSamples = curveData.NodeSamples, RepeatCount = curveData.RepeatCount, Position = positionData?.Position ?? Vector2.Zero, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, LegacyLastTickOffset = legacyOffset?.LegacyLastTickOffset, // prior to v8, speed multipliers don't adjust for how many ticks are generated over the same distance. // this results in more (or less) ticks being generated in <v8 maps for the same time duration. TickDistanceMultiplier = beatmap.BeatmapInfo.BeatmapVersion < 8 ? 1f / beatmap.ControlPointInfo.DifficultyPointAt(original.StartTime).SpeedMultiplier : 1 }); } else if (endTimeData != null) { yield return(new Spinner { StartTime = original.StartTime, Samples = original.Samples, EndTime = endTimeData.EndTime, Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, }); } else { yield return(new HitCircle { StartTime = original.StartTime, Samples = original.Samples, Position = positionData?.Position ?? Vector2.Zero, NewCombo = comboData?.NewCombo ?? false, ComboOffset = comboData?.ComboOffset ?? 0, }); } }
protected AutoGenerator(IBeatmap beatmap) { Beatmap = beatmap; }