1
0
mirror of https://github.com/ppy/osu.git synced 2024-10-01 02:57:24 +08:00
This commit is contained in:
KoziLord 2018-05-15 12:23:36 +02:00
commit 08386d6ca4
50 changed files with 396 additions and 230 deletions

View File

@ -14,6 +14,8 @@ using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty;
using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Catch
{

View File

@ -1,10 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets.Catch
namespace osu.Game.Rulesets.Catch.Difficulty
{
public class CatchDifficultyCalculator : DifficultyCalculator
{

View File

@ -47,6 +47,8 @@ namespace osu.Game.Rulesets.Catch.Objects
Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5;
}
protected override HitWindows CreateHitWindows() => null;
}
public enum FruitVisualRepresentation

View File

@ -4,6 +4,8 @@
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Tests.Visual;
@ -17,6 +19,14 @@ namespace osu.Game.Rulesets.Mania.Tests
{
public TestCaseManiaHitObjects()
{
Note note1 = new Note();
Note note2 = new Note();
HoldNote holdNote = new HoldNote { StartTime = 1000 };
note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
Add(new FillFlowContainer
{
Anchor = Anchor.Centre,
@ -43,14 +53,14 @@ namespace osu.Game.Rulesets.Mania.Tests
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableNote(new Note(), ManiaAction.Key1)
new DrawableNote(note1, ManiaAction.Key1)
{
Y = 5000,
LifetimeStart = double.MinValue,
LifetimeEnd = double.MaxValue,
AccentColour = Color4.Red
},
new DrawableNote(new Note(), ManiaAction.Key1)
new DrawableNote(note2, ManiaAction.Key1)
{
Y = 6000,
LifetimeStart = double.MinValue,
@ -77,13 +87,13 @@ namespace osu.Game.Rulesets.Mania.Tests
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableHoldNote(new HoldNote { Duration = 1000 } , ManiaAction.Key1)
new DrawableHoldNote(holdNote, ManiaAction.Key1)
{
Y = 5000,
Height = 1000,
LifetimeStart = double.MinValue,
LifetimeEnd = double.MaxValue,
AccentColour = Color4.Red
AccentColour = Color4.Red,
}
}
}

View File

@ -8,6 +8,8 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Configuration;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
@ -83,13 +85,16 @@ namespace osu.Game.Rulesets.Mania.Tests
int col = rng.Next(0, 4);
var note = new DrawableNote(new Note { Column = col }, ManiaAction.Key1)
var note = new Note { Column = col };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
var drawableNote = new DrawableNote(note, ManiaAction.Key1)
{
AccentColour = playfield.Columns.ElementAt(col).AccentColour
};
playfield.OnJudgement(note, new ManiaJudgement { Result = HitResult.Perfect });
playfield.Columns[col].OnJudgement(note, new ManiaJudgement { Result = HitResult.Perfect });
playfield.OnJudgement(drawableNote, new ManiaJudgement { Result = HitResult.Perfect });
playfield.Columns[col].OnJudgement(drawableNote, new ManiaJudgement { Result = HitResult.Perfect });
});
}
@ -162,32 +167,24 @@ namespace osu.Game.Rulesets.Mania.Tests
for (double t = start_time; t <= start_time + duration; t += 100)
{
playfield.Add(new DrawableNote(new Note
{
StartTime = t,
Column = 0
}, ManiaAction.Key1));
var note1 = new Note { StartTime = t, Column = 0 };
var note2 = new Note { StartTime = t, Column = 3 };
playfield.Add(new DrawableNote(new Note
{
StartTime = t,
Column = 3
}, ManiaAction.Key4));
note1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
note2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
playfield.Add(new DrawableNote(note1, ManiaAction.Key1));
playfield.Add(new DrawableNote(note2, ManiaAction.Key4));
}
playfield.Add(new DrawableHoldNote(new HoldNote
{
StartTime = start_time,
Duration = duration,
Column = 1
}, ManiaAction.Key2));
var holdNote1 = new HoldNote { StartTime = start_time, Duration = duration, Column = 1 };
var holdNote2 = new HoldNote { StartTime = start_time, Duration = duration, Column = 2 };
playfield.Add(new DrawableHoldNote(new HoldNote
{
StartTime = start_time,
Duration = duration,
Column = 2
}, ManiaAction.Key3));
holdNote1.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
holdNote2.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
playfield.Add(new DrawableHoldNote(holdNote1, ManiaAction.Key2));
playfield.Add(new DrawableHoldNote(holdNote2, ManiaAction.Key3));
}
}
}

View File

@ -59,7 +59,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original)
{
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate);
@ -85,7 +84,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
yield break;
foreach (ManiaHitObject obj in objects)
{
obj.HitWindows = original.HitWindows;
yield return obj;
}
}
private readonly List<double> prevNoteTimes = new List<double>(max_notes_for_density);

View File

@ -1,14 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
namespace osu.Game.Rulesets.Mania
namespace osu.Game.Rulesets.Mania.Difficulty
{
internal class ManiaDifficultyCalculator : DifficultyCalculator
{

View File

@ -15,7 +15,9 @@ using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Difficulty;
namespace osu.Game.Rulesets.Mania
{

View File

@ -103,6 +103,7 @@ namespace osu.Game.Rulesets.Mania.Objects
/// <summary>
/// Lenience of release hit windows. This is to make cases where the hold note release
/// is timed alongside presses of other hit objects less awkward.
/// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps
/// </summary>
private const double release_window_lenience = 1.5;

View File

@ -93,12 +93,36 @@ namespace osu.Game.Rulesets.Osu.Tests
AddStep("Big Single, Large StackOffset", () => testSimpleBigLargeStackOffset());
AddStep("Big 1 Repeat, Large StackOffset", () => testSimpleBigLargeStackOffset(1));
AddStep("Distance Overflow", () => testDistanceOverflow());
AddStep("Distance Overflow 1 Repeat", () => testDistanceOverflow(1));
}
private void testSimpleBig(int repeats = 0) => createSlider(2, repeats: repeats);
private void testSimpleBigLargeStackOffset(int repeats = 0) => createSlider(2, repeats: repeats, stackHeight: 10);
private void testDistanceOverflow(int repeats = 0)
{
var slider = new Slider
{
StartTime = Time.Current + 1000,
Position = new Vector2(239, 176),
ControlPoints = new List<Vector2>
{
Vector2.Zero,
new Vector2(154, 28),
new Vector2(52, -34)
},
Distance = 700,
RepeatCount = repeats,
RepeatSamples = createEmptySamples(repeats),
StackHeight = 10
};
addSlider(slider, 2, 2);
}
private void testSimpleMedium(int repeats = 0) => createSlider(5, repeats: repeats);
private void testSimpleSmall(int repeats = 0) => createSlider(7, repeats: repeats);

View File

@ -40,7 +40,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
RepeatSamples = curveData.RepeatSamples,
RepeatCount = curveData.RepeatCount,
Position = positionData?.Position ?? Vector2.Zero,
NewCombo = comboData?.NewCombo ?? false
NewCombo = comboData?.NewCombo ?? false,
HitWindows = original.HitWindows
};
}
else if (endTimeData != null)
@ -50,8 +51,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
StartTime = original.StartTime,
Samples = original.Samples,
EndTime = endTimeData.EndTime,
Position = positionData?.Position ?? OsuPlayfield.BASE_SIZE / 2,
HitWindows = original.HitWindows
};
}
else
@ -61,7 +62,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
StartTime = original.StartTime,
Samples = original.Samples,
Position = positionData?.Position ?? Vector2.Zero,
NewCombo = comboData?.NewCombo ?? false
NewCombo = comboData?.NewCombo ?? false,
HitWindows = original.HitWindows
};
}
}

View File

@ -4,12 +4,13 @@
using System;
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Difficulty.Skills;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
using osu.Game.Rulesets.Osu.OsuDifficulty.Skills;
namespace osu.Game.Rulesets.Osu.OsuDifficulty
namespace osu.Game.Rulesets.Osu.Difficulty
{
public class OsuDifficultyCalculator : DifficultyCalculator
{

View File

@ -5,7 +5,7 @@ using System.Collections;
using System.Collections.Generic;
using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing
namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
{
/// <summary>
/// An enumerable container wrapping <see cref="OsuHitObject"/> input as <see cref="OsuDifficultyHitObject"/>

View File

@ -3,10 +3,10 @@
using System;
using System.Linq;
using OpenTK;
using osu.Game.Rulesets.Osu.Objects;
using OpenTK;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing
namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
{
/// <summary>
/// A wrapper around <see cref="OsuHitObject"/> extending it with additional data required for difficulty calculation.

View File

@ -2,9 +2,9 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
/// <summary>
/// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances.

View File

@ -3,11 +3,11 @@
using System;
using System.Collections.Generic;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Difficulty.Utils;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
using osu.Game.Rulesets.Osu.OsuDifficulty.Utils;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
/// <summary>
/// Used to processes strain values of <see cref="OsuDifficultyHitObject"/>s, keep track of strain levels caused by the processed objects

View File

@ -1,9 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Skills
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
/// <summary>
/// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit.

View File

@ -5,7 +5,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
namespace osu.Game.Rulesets.Osu.OsuDifficulty.Utils
namespace osu.Game.Rulesets.Osu.Difficulty.Utils
{
/// <summary>
/// An indexed stack with Push() only, which disposes items at the bottom after the capacity is full.

View File

@ -5,7 +5,6 @@ using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.OsuDifficulty;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
@ -19,7 +18,9 @@ using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Osu.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Rulesets.Osu.Difficulty;
namespace osu.Game.Rulesets.Osu
{

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
@ -138,8 +139,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
aimValue *= approachRateFactor;
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
if (mods.Any(h => h is OsuModHidden))
aimValue *= 1.03f;
aimValue *= 1.02 + (11.0f - realApproachRate) / 50.0; // Gives a 1.04 bonus for AR10, a 1.06 bonus for AR9, a 1.02 bonus for AR11.
if (mods.Any(h => h is OsuModFlashlight))
{

View File

@ -132,7 +132,8 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{
StartTime = j,
Samples = currentSamples,
IsStrong = strong
IsStrong = strong,
HitWindows = obj.HitWindows
};
}
else
@ -142,6 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
StartTime = j,
Samples = currentSamples,
IsStrong = strong,
HitWindows = obj.HitWindows
};
}
@ -157,6 +159,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
IsStrong = strong,
Duration = taikoDuration,
TickRate = beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate == 3 ? 3 : 4,
HitWindows = obj.HitWindows
};
}
}
@ -171,6 +174,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
IsStrong = strong,
Duration = endTimeData.Duration,
RequiredHits = (int)Math.Max(1, endTimeData.Duration / 1000 * hitMultiplier),
HitWindows = obj.HitWindows
};
}
else
@ -184,6 +188,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
StartTime = obj.StartTime,
Samples = obj.Samples,
IsStrong = strong,
HitWindows = obj.HitWindows
};
}
else
@ -193,6 +198,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
StartTime = obj.StartTime,
Samples = obj.Samples,
IsStrong = strong,
HitWindows = obj.HitWindows
};
}
}

View File

@ -1,12 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Taiko.Objects;
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Taiko.Objects;
namespace osu.Game.Rulesets.Taiko
namespace osu.Game.Rulesets.Taiko.Difficulty
{
internal class TaikoDifficultyCalculator : DifficultyCalculator
{

View File

@ -13,7 +13,9 @@ using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.Taiko.Replays;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Taiko.Beatmaps;
using osu.Game.Rulesets.Taiko.Difficulty;
namespace osu.Game.Rulesets.Taiko
{

View File

@ -9,6 +9,7 @@ using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Tests.Resources;
using OpenTK;
@ -117,7 +118,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
public void TestParity(string beatmap)
{
var legacy = decode(beatmap, out Beatmap json);
json.ShouldDeepEqual(legacy);
json.WithDeepEqual(legacy).IgnoreProperty(r => r.DeclaringType == typeof(HitWindows)).Assert();
}
/// <summary>

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.UI;

View File

@ -4,7 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Music
{
public class PlaylistList : CompositeDrawable
{
public Action<BeatmapSetInfo> OnSelect;
public Action<BeatmapSetInfo> Selected;
public Action<BeatmapSetInfo, int> OrderChanged;
private readonly ItemsScrollContainer items;
@ -25,7 +27,8 @@ namespace osu.Game.Overlays.Music
InternalChild = items = new ItemsScrollContainer
{
RelativeSizeAxes = Axes.Both,
OnSelect = set => OnSelect?.Invoke(set)
Selected = set => Selected?.Invoke(set),
OrderChanged = (s, i) => OrderChanged?.Invoke(s, i)
};
}
@ -35,34 +38,20 @@ namespace osu.Game.Overlays.Music
set { base.Padding = value; }
}
public IEnumerable<BeatmapSetInfo> BeatmapSets
{
get { return items.Sets; }
set { items.Sets = value; }
}
public BeatmapSetInfo FirstVisibleSet => items.FirstVisibleSet;
public BeatmapSetInfo NextSet => items.NextSet;
public BeatmapSetInfo PreviousSet => items.PreviousSet;
public BeatmapSetInfo SelectedSet
{
get { return items.SelectedSet; }
set { items.SelectedSet = value; }
}
public void AddBeatmapSet(BeatmapSetInfo beatmapSet) => items.AddBeatmapSet(beatmapSet);
public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) => items.RemoveBeatmapSet(beatmapSet);
public void Filter(string searchTerm) => items.SearchTerm = searchTerm;
private class ItemsScrollContainer : OsuScrollContainer
{
public Action<BeatmapSetInfo> OnSelect;
public Action<BeatmapSetInfo> Selected;
public Action<BeatmapSetInfo, int> OrderChanged;
private readonly SearchContainer search;
private readonly FillFlowContainer<PlaylistItem> items;
private readonly IBindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
public ItemsScrollContainer()
{
Children = new Drawable[]
@ -83,14 +72,36 @@ namespace osu.Game.Overlays.Music
};
}
public IEnumerable<BeatmapSetInfo> Sets
[BackgroundDependencyLoader]
private void load(BeatmapManager beatmaps, OsuGameBase osuGame)
{
get { return items.Select(x => x.BeatmapSetInfo).ToList(); }
set
{
items.Clear();
value.ForEach(AddBeatmapSet);
}
beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet);
beatmaps.ItemAdded += addBeatmapSet;
beatmaps.ItemRemoved += removeBeatmapSet;
beatmapBacking.BindTo(osuGame.Beatmap);
beatmapBacking.ValueChanged += _ => updateSelectedSet();
}
private void addBeatmapSet(BeatmapSetInfo obj)
{
var newItem = new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) };
items.Add(newItem);
items.SetLayoutPosition(newItem, items.Count - 1);
}
private void removeBeatmapSet(BeatmapSetInfo obj)
{
var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == obj.ID);
if (itemToRemove != null)
items.Remove(itemToRemove);
}
private void updateSelectedSet()
{
foreach (PlaylistItem s in items.Children)
s.Selected = s.BeatmapSetInfo.ID == beatmapBacking.Value.BeatmapSetInfo.ID;
}
public string SearchTerm
@ -99,34 +110,7 @@ namespace osu.Game.Overlays.Music
set { search.SearchTerm = value; }
}
public void AddBeatmapSet(BeatmapSetInfo beatmapSet)
{
var newItem = new PlaylistItem(beatmapSet) { OnSelect = set => OnSelect?.Invoke(set) };
items.Add(newItem);
items.SetLayoutPosition(newItem, items.Count);
}
public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet)
{
var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == beatmapSet.ID);
if (itemToRemove != null)
items.Remove(itemToRemove);
}
public BeatmapSetInfo SelectedSet
{
get { return items.FirstOrDefault(i => i.Selected)?.BeatmapSetInfo; }
set
{
foreach (PlaylistItem s in items.Children)
s.Selected = s.BeatmapSetInfo.ID == value?.ID;
}
}
public BeatmapSetInfo FirstVisibleSet => items.FirstOrDefault(i => i.MatchingFilter)?.BeatmapSetInfo;
public BeatmapSetInfo NextSet => (items.SkipWhile(i => !i.Selected).Skip(1).FirstOrDefault() ?? items.FirstOrDefault())?.BeatmapSetInfo;
public BeatmapSetInfo PreviousSet => (items.TakeWhile(i => !i.Selected).LastOrDefault() ?? items.LastOrDefault())?.BeatmapSetInfo;
private Vector2 nativeDragPosition;
private PlaylistItem draggedItem;
@ -227,6 +211,7 @@ namespace osu.Game.Overlays.Music
}
items.SetLayoutPosition(draggedItem, dstIndex);
OrderChanged?.Invoke(draggedItem.BeatmapSetInfo, dstIndex);
}
private class ItemSearchContainer : FillFlowContainer<PlaylistItem>, IHasFilterableChildren

View File

@ -1,7 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
@ -19,18 +19,16 @@ namespace osu.Game.Overlays.Music
public class PlaylistOverlay : OverlayContainer
{
private const float transition_duration = 600;
private const float playlist_height = 510;
public Action<BeatmapSetInfo, int> OrderChanged;
private BeatmapManager beatmaps;
private FilterControl filter;
private PlaylistList list;
private BeatmapManager beatmaps;
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
public IEnumerable<BeatmapSetInfo> BeatmapSets => list.BeatmapSets;
[BackgroundDependencyLoader]
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours)
{
@ -60,7 +58,8 @@ namespace osu.Game.Overlays.Music
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 },
OnSelect = itemSelected,
Selected = itemSelected,
OrderChanged = (s, i) => OrderChanged?.Invoke(s, i)
},
filter = new FilterControl
{
@ -74,30 +73,16 @@ namespace osu.Game.Overlays.Music
},
};
beatmaps.ItemAdded += handleBeatmapAdded;
beatmaps.ItemRemoved += handleBeatmapRemoved;
list.BeatmapSets = beatmaps.GetAllUsableBeatmapSets();
beatmapBacking.BindTo(game.Beatmap);
filter.Search.OnCommit = (sender, newText) =>
{
var beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
if (beatmap != null) playSpecified(beatmap);
BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault();
if (beatmap != null)
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap);
};
}
protected override void LoadComplete()
{
base.LoadComplete();
beatmapBacking.ValueChanged += b => list.SelectedSet = b?.BeatmapSetInfo;
beatmapBacking.TriggerChange();
}
private void handleBeatmapAdded(BeatmapSetInfo setInfo) => Schedule(() => list.AddBeatmapSet(setInfo));
private void handleBeatmapRemoved(BeatmapSetInfo setInfo) => Schedule(() => list.RemoveBeatmapSet(setInfo));
protected override void PopIn()
{
filter.Search.HoldFocus = true;
@ -123,49 +108,7 @@ namespace osu.Game.Overlays.Music
return;
}
playSpecified(set.Beatmaps.First());
}
public void PlayPrevious()
{
var playable = list.PreviousSet;
if (playable != null)
{
playSpecified(playable.Beatmaps.First());
list.SelectedSet = playable;
}
}
public void PlayNext()
{
var playable = list.NextSet;
if (playable != null)
{
playSpecified(playable.Beatmaps.First());
list.SelectedSet = playable;
}
}
private void playSpecified(BeatmapInfo info)
{
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(info, beatmapBacking);
var track = beatmapBacking.Value.Track;
track.Restart();
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (beatmaps != null)
{
beatmaps.ItemAdded -= handleBeatmapAdded;
beatmaps.ItemRemoved -= handleBeatmapRemoved;
}
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First());
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Allocation;
@ -50,7 +51,10 @@ namespace osu.Game.Overlays
private LocalisationEngine localisation;
private BeatmapManager beatmaps;
private readonly Bindable<WorkingBeatmap> beatmapBacking = new Bindable<WorkingBeatmap>();
private List<BeatmapSetInfo> beatmapSets;
private BeatmapSetInfo currentSet;
private Container dragContainer;
private Container playerContainer;
@ -93,8 +97,9 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
private void load(OsuGameBase game, OsuColour colours, LocalisationEngine localisation)
private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation)
{
this.beatmaps = beatmaps;
this.localisation = localisation;
Children = new Drawable[]
@ -111,6 +116,7 @@ namespace osu.Game.Overlays
{
RelativeSizeAxes = Axes.X,
Y = player_height + 10,
OrderChanged = playlistOrderChanged
},
playerContainer = new Container
{
@ -185,7 +191,7 @@ namespace osu.Game.Overlays
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Action = next,
Action = () => next(),
Icon = FontAwesome.fa_step_forward,
},
}
@ -214,11 +220,24 @@ namespace osu.Game.Overlays
}
};
beatmapSets = beatmaps.GetAllUsableBeatmapSets();
beatmaps.ItemAdded += handleBeatmapAdded;
beatmaps.ItemRemoved += handleBeatmapRemoved;
beatmapBacking.BindTo(game.Beatmap);
playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint);
}
private void playlistOrderChanged(BeatmapSetInfo beatmapSetInfo, int index)
{
beatmapSets.Remove(beatmapSetInfo);
beatmapSets.Insert(index, beatmapSetInfo);
}
private void handleBeatmapAdded(BeatmapSetInfo obj) => beatmapSets.Add(obj);
private void handleBeatmapRemoved(BeatmapSetInfo obj) => beatmapSets.RemoveAll(s => s.ID == obj.ID);
protected override void LoadComplete()
{
beatmapBacking.ValueChanged += beatmapChanged;
@ -257,7 +276,7 @@ namespace osu.Game.Overlays
playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o;
if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && playlist.BeatmapSets.Any())
if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any())
next();
}
else
@ -271,7 +290,7 @@ namespace osu.Game.Overlays
if (track == null)
{
if (!beatmapBacking.Disabled)
playlist.PlayNext();
next(true);
return;
}
@ -284,13 +303,26 @@ namespace osu.Game.Overlays
private void prev()
{
queuedDirection = TransformDirection.Prev;
playlist.PlayPrevious();
var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault();
if (playable != null)
{
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
beatmapBacking.Value.Track.Restart();
}
}
private void next()
private void next(bool instant = false)
{
queuedDirection = TransformDirection.Next;
playlist.PlayNext();
if (!instant)
queuedDirection = TransformDirection.Next;
var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault();
if (playable != null)
{
beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking);
beatmapBacking.Value.Track.Restart();
}
}
private WorkingBeatmap current;
@ -314,8 +346,8 @@ namespace osu.Game.Overlays
else
{
//figure out the best direction based on order in playlist.
var last = playlist.BeatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count();
var next = beatmap == null ? -1 : playlist.BeatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count();
var last = beatmapSets.TakeWhile(b => b.ID != current.BeatmapSetInfo?.ID).Count();
var next = beatmap == null ? -1 : beatmapSets.TakeWhile(b => b.ID != beatmap.BeatmapSetInfo?.ID).Count();
direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
}

View File

@ -2,12 +2,13 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Rulesets.Mods;
using osu.Framework.Timing;
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Beatmaps
namespace osu.Game.Rulesets.Difficulty
{
public abstract class DifficultyCalculator
{

View File

@ -7,8 +7,9 @@ using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Scoring
namespace osu.Game.Rulesets.Difficulty
{
public abstract class PerformanceCalculator
{

View File

@ -51,16 +51,10 @@ namespace osu.Game.Rulesets.Objects
private float overallDifficulty = BeatmapDifficulty.DEFAULT_DIFFICULTY;
private HitWindows hitWindows;
/// <summary>
/// The hit windows for this <see cref="HitObject"/>.
/// </summary>
public HitWindows HitWindows
{
get => hitWindows ?? (hitWindows = new HitWindows(overallDifficulty));
protected set => hitWindows = value;
}
public HitWindows HitWindows { get; set; }
private readonly SortedList<HitObject> nestedHitObjects = new SortedList<HitObject>((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
@ -78,7 +72,11 @@ namespace osu.Game.Rulesets.Objects
nestedHitObjects.Clear();
CreateNestedHitObjects();
nestedHitObjects.ForEach(h => h.ApplyDefaults(controlPointInfo, difficulty));
nestedHitObjects.ForEach(h =>
{
h.HitWindows = HitWindows;
h.ApplyDefaults(controlPointInfo, difficulty);
});
}
protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
@ -89,8 +87,9 @@ namespace osu.Game.Rulesets.Objects
Kiai = effectPoint.KiaiMode;
SampleControlPoint = samplePoint;
overallDifficulty = difficulty.OverallDifficulty;
hitWindows = null;
if (HitWindows == null)
HitWindows = CreateHitWindows();
HitWindows?.SetDifficulty(difficulty.OverallDifficulty);
}
protected virtual void CreateNestedHitObjects()
@ -98,5 +97,14 @@ namespace osu.Game.Rulesets.Objects
}
protected void AddNested(HitObject hitObject) => nestedHitObjects.Add(hitObject);
/// <summary>
/// Creates the <see cref="HitWindows"/> for this <see cref="HitObject"/>.
/// This can be null to indicate that the <see cref="HitObject"/> has no <see cref="HitWindows"/>.
/// <para>
/// This will only be invoked if <see cref="HitWindows"/> hasn't been set externally (e.g. from a <see cref="BeatmapConverter"/>.
/// </para>
/// </summary>
protected virtual HitWindows CreateHitWindows() => new HitWindows();
}
}

View File

@ -63,10 +63,10 @@ namespace osu.Game.Rulesets.Objects
public bool AllowsOk;
/// <summary>
/// Constructs hit windows by fitting a parameter to a 2-part piecewise linear function for each hit window.
/// Sets hit windows with values that correspond to a difficulty parameter.
/// </summary>
/// <param name="difficulty">The parameter.</param>
public HitWindows(double difficulty)
public virtual void SetDifficulty(double difficulty)
{
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);

View File

@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
public float X { get; set; }
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -0,0 +1,32 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Objects.Legacy.Mania
{
public class ConvertHitWindows : HitWindows
{
private static readonly IReadOnlyDictionary<HitResult, (double od0, double od5, double od10)> base_ranges = new Dictionary<HitResult, (double, double, double)>
{
{ HitResult.Perfect, (44.8, 38.8, 27.8) },
{ HitResult.Great, (128, 98, 68 ) },
{ HitResult.Good, (194, 164, 134) },
{ HitResult.Ok, (254, 224, 194) },
{ HitResult.Meh, (302, 272, 242) },
{ HitResult.Miss, (376, 346, 316) },
};
public override void SetDifficulty(double difficulty)
{
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
Ok = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Ok]);
Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]);
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
}
}
}

View File

@ -12,5 +12,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
public float X { get; set; }
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -15,5 +15,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania
public double Duration => EndTime - StartTime;
public float X { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -18,5 +18,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
public float Y => Position.Y;
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Objects.Legacy.Osu
{
public class ConvertHitWindows : HitWindows
{
private static readonly IReadOnlyDictionary<HitResult, (double od0, double od5, double od10)> base_ranges = new Dictionary<HitResult, (double, double, double)>
{
{ HitResult.Great, (160, 100, 40) },
{ HitResult.Good, (280, 200, 120) },
{ HitResult.Meh, (400, 300, 200) },
{ HitResult.Miss, (400, 400, 400) },
};
public override void SetDifficulty(double difficulty)
{
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]);
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
}
}
}

View File

@ -18,5 +18,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
public float Y => Position.Y;
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -20,5 +20,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu
public float X => Position.X;
public float Y => Position.Y;
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -11,5 +11,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
internal sealed class ConvertHit : HitObject, IHasCombo
{
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -0,0 +1,28 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Objects.Legacy.Taiko
{
public class ConvertHitWindows : HitWindows
{
private static readonly IReadOnlyDictionary<HitResult, (double od0, double od5, double od10)> base_ranges = new Dictionary<HitResult, (double, double, double)>
{
{ HitResult.Great, (100, 70, 40) },
{ HitResult.Good, (240, 160, 100) },
{ HitResult.Meh, (270, 190, 140) },
{ HitResult.Miss, (400, 400, 400) },
};
public override void SetDifficulty(double difficulty)
{
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]);
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
}
}
}

View File

@ -11,5 +11,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
internal sealed class ConvertSlider : Legacy.ConvertSlider, IHasCombo
{
public bool NewCombo { get; set; }
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko
public double EndTime { get; set; }
public double Duration => EndTime - StartTime;
protected override HitWindows CreateHitWindows() => new ConvertHitWindows();
}
}

View File

@ -99,11 +99,9 @@ namespace osu.Game.Rulesets.Objects
cumulativeLength.Add(l);
}
//TODO: Figure out if the following code is needed in some cases. Judging by the map
// "Transform" http://osu.ppy.sh/s/484689 it seems like we should _not_ be doing this.
// Lengthen slider curves that are too short compared to what's
// in the .osu file.
/*if (l < Length && calculatedPath.Count > 1)
if (l < Distance && calculatedPath.Count > 1)
{
Vector2 diff = calculatedPath[calculatedPath.Count - 1] - calculatedPath[calculatedPath.Count - 2];
double d = diff.Length;
@ -111,9 +109,9 @@ namespace osu.Game.Rulesets.Objects
if (d <= 0)
return;
calculatedPath[calculatedPath.Count - 1] += diff * (float)((Length - l) / d);
cumulativeLength[calculatedPath.Count - 1] = Length;
}*/
calculatedPath[calculatedPath.Count - 1] += diff * (float)((Distance - l) / d);
cumulativeLength[calculatedPath.Count - 1] = Distance;
}
}
public void Calculate()

View File

@ -15,6 +15,7 @@ using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Difficulty;
namespace osu.Game.Rulesets
{

View File

@ -0,0 +1,26 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
namespace osu.Game.Rulesets.Scoring.Legacy
{
/// <summary>
/// A <see cref="LegacyScoreParser"/> which retrieves the applicable <see cref="Beatmap"/> and <see cref="Ruleset"/>
/// for the score from the database.
/// </summary>
public class DatabasedLegacyScoreParser : LegacyScoreParser
{
private readonly RulesetStore rulesets;
private readonly BeatmapManager beatmaps;
public DatabasedLegacyScoreParser(RulesetStore rulesets, BeatmapManager beatmaps)
{
this.rulesets = rulesets;
this.beatmaps = beatmaps;
}
protected override Ruleset GetRuleset(int rulesetId) => rulesets.GetRuleset(rulesetId).CreateInstance();
protected override WorkingBeatmap GetBeatmap(string md5Hash) => beatmaps.GetWorkingBeatmap(beatmaps.QueryBeatmap(b => b.MD5Hash == md5Hash));
}
}

View File

@ -14,17 +14,8 @@ using System.Linq;
namespace osu.Game.Rulesets.Scoring.Legacy
{
public class LegacyScoreParser
public abstract class LegacyScoreParser
{
private readonly RulesetStore rulesets;
private readonly BeatmapManager beatmaps;
public LegacyScoreParser(RulesetStore rulesets, BeatmapManager beatmaps)
{
this.rulesets = rulesets;
this.beatmaps = beatmaps;
}
private IBeatmap currentBeatmap;
private Ruleset currentRuleset;
@ -34,16 +25,15 @@ namespace osu.Game.Rulesets.Scoring.Legacy
using (SerializationReader sr = new SerializationReader(stream))
{
score = new Score { Ruleset = rulesets.GetRuleset(sr.ReadByte()) };
currentRuleset = score.Ruleset.CreateInstance();
currentRuleset = GetRuleset(sr.ReadByte());
score = new Score { Ruleset = currentRuleset.RulesetInfo };
/* score.Pass = true;*/
var version = sr.ReadInt32();
/* score.FileChecksum = */
var beatmapHash = sr.ReadString();
score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash);
currentBeatmap = beatmaps.GetWorkingBeatmap(score.Beatmap).Beatmap;
currentBeatmap = GetBeatmap(sr.ReadString()).Beatmap;
score.Beatmap = currentBeatmap.BeatmapInfo;
/* score.PlayerName = */
score.User = new User { Username = sr.ReadString() };
@ -181,5 +171,19 @@ namespace osu.Game.Rulesets.Scoring.Legacy
return frame;
}
/// <summary>
/// Retrieves the <see cref="Ruleset"/> for a specific id.
/// </summary>
/// <param name="rulesetId">The id.</param>
/// <returns>The <see cref="Ruleset"/>.</returns>
protected abstract Ruleset GetRuleset(int rulesetId);
/// <summary>
/// Retrieves the <see cref="WorkingBeatmap"/> corresponding to an MD5 hash.
/// </summary>
/// <param name="md5Hash">The MD5 hash.</param>
/// <returns>The <see cref="WorkingBeatmap"/>.</returns>
protected abstract WorkingBeatmap GetBeatmap(string md5Hash);
}
}

View File

@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Scoring
public Score ReadReplayFile(string replayFilename)
{
using (Stream s = storage.GetStream(Path.Combine(replay_folder, replayFilename)))
return new LegacyScoreParser(rulesets, beatmaps).Parse(s);
return new DatabasedLegacyScoreParser(rulesets, beatmaps).Parse(s);
}
}
}