mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 03:02:54 +08:00
Merge branch 'master' into scrolling-hitobjects-rewrite
This commit is contained in:
commit
1276e2c71a
33
osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
Normal file
33
osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) 2007-2017 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.Linq;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||||
|
{
|
||||||
|
public class ManiaBeatmap : Beatmap<ManiaHitObject>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The definitions for each stage in a <see cref="ManiaPlayfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<StageDefinition> Stages = new List<StageDefinition>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of columns represented by all stages in this <see cref="ManiaBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
public int TotalColumns => Stages.Sum(g => g.Columns);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ManiaBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="initialStage">The initial stage.</param>
|
||||||
|
public ManiaBeatmap(StageDefinition initialStage)
|
||||||
|
{
|
||||||
|
Stages.Add(initialStage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -24,24 +25,39 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
||||||
|
|
||||||
|
public int TargetColumns;
|
||||||
|
public readonly bool IsForCurrentRuleset;
|
||||||
|
|
||||||
private Pattern lastPattern = new Pattern();
|
private Pattern lastPattern = new Pattern();
|
||||||
private FastRandom random;
|
private FastRandom random;
|
||||||
private Beatmap beatmap;
|
|
||||||
|
|
||||||
private readonly int availableColumns;
|
private ManiaBeatmap beatmap;
|
||||||
private readonly bool isForCurrentRuleset;
|
|
||||||
|
|
||||||
public ManiaBeatmapConverter(bool isForCurrentRuleset, int availableColumns)
|
public ManiaBeatmapConverter(bool isForCurrentRuleset, Beatmap original)
|
||||||
{
|
{
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
IsForCurrentRuleset = isForCurrentRuleset;
|
||||||
|
|
||||||
this.isForCurrentRuleset = isForCurrentRuleset;
|
var roundedCircleSize = Math.Round(original.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||||
this.availableColumns = availableColumns;
|
var roundedOverallDifficulty = Math.Round(original.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||||
|
|
||||||
|
if (isForCurrentRuleset)
|
||||||
|
TargetColumns = (int)Math.Max(1, roundedCircleSize);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float percentSliderOrSpinner = (float)original.HitObjects.Count(h => h is IHasEndTime) / original.HitObjects.Count;
|
||||||
|
if (percentSliderOrSpinner < 0.2)
|
||||||
|
TargetColumns = 7;
|
||||||
|
else if (percentSliderOrSpinner < 0.3 || roundedCircleSize >= 5)
|
||||||
|
TargetColumns = roundedOverallDifficulty > 5 ? 7 : 6;
|
||||||
|
else if (percentSliderOrSpinner > 0.6)
|
||||||
|
TargetColumns = roundedOverallDifficulty > 4 ? 5 : 4;
|
||||||
|
else
|
||||||
|
TargetColumns = Math.Max(4, Math.Min((int)roundedOverallDifficulty + 1, 7));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
protected override Beatmap<ManiaHitObject> ConvertBeatmap(Beatmap original)
|
||||||
{
|
{
|
||||||
beatmap = original;
|
|
||||||
|
|
||||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||||
|
|
||||||
@ -51,6 +67,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
return base.ConvertBeatmap(original);
|
return base.ConvertBeatmap(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Beatmap<ManiaHitObject> CreateBeatmap() => beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns });
|
||||||
|
|
||||||
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
protected override IEnumerable<ManiaHitObject> ConvertHitObject(HitObject original, Beatmap beatmap)
|
||||||
{
|
{
|
||||||
var maniaOriginal = original as ManiaHitObject;
|
var maniaOriginal = original as ManiaHitObject;
|
||||||
@ -60,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var objects = isForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
var objects = IsForCurrentRuleset ? generateSpecific(original) : generateConverted(original);
|
||||||
|
|
||||||
if (objects == null)
|
if (objects == null)
|
||||||
yield break;
|
yield break;
|
||||||
@ -96,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// <returns>The hit objects generated.</returns>
|
/// <returns>The hit objects generated.</returns>
|
||||||
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
|
private IEnumerable<ManiaHitObject> generateSpecific(HitObject original)
|
||||||
{
|
{
|
||||||
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
|
var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern);
|
||||||
|
|
||||||
Pattern newPattern = generator.Generate();
|
Pattern newPattern = generator.Generate();
|
||||||
lastPattern = newPattern;
|
lastPattern = newPattern;
|
||||||
@ -120,14 +138,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
Patterns.PatternGenerator conversion = null;
|
Patterns.PatternGenerator conversion = null;
|
||||||
|
|
||||||
if (distanceData != null)
|
if (distanceData != null)
|
||||||
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern);
|
conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern);
|
||||||
else if (endTimeData != null)
|
else if (endTimeData != null)
|
||||||
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, availableColumns);
|
conversion = new EndTimeObjectPatternGenerator(random, original, beatmap);
|
||||||
else if (positionData != null)
|
else if (positionData != null)
|
||||||
{
|
{
|
||||||
computeDensity(original.StartTime);
|
computeDensity(original.StartTime);
|
||||||
|
|
||||||
conversion = new HitObjectPatternGenerator(random, original, beatmap, availableColumns, lastPattern, lastTime, lastPosition, density, lastStair);
|
conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair);
|
||||||
|
|
||||||
recordNote(original.StartTime, positionData.Position);
|
recordNote(original.StartTime, positionData.Position);
|
||||||
}
|
}
|
||||||
@ -149,8 +167,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator
|
||||||
{
|
{
|
||||||
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -30,8 +29,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private PatternType convertType;
|
private PatternType convertType;
|
||||||
|
|
||||||
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
convertType = PatternType.None;
|
convertType = PatternType.None;
|
||||||
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
|
if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode)
|
||||||
@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (duration >= 4000)
|
if (duration >= 4000)
|
||||||
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0);
|
||||||
|
|
||||||
if (segmentDuration > 400 && repeatCount < AvailableColumns - 1 - RandomStart)
|
if (segmentDuration > 400 && repeatCount < TotalColumns - 1 - RandomStart)
|
||||||
return generateTiledHoldNotes(HitObject.StartTime);
|
return generateTiledHoldNotes(HitObject.StartTime);
|
||||||
|
|
||||||
return generateHoldAndNormalNotes(HitObject.StartTime);
|
return generateHoldAndNormalNotes(HitObject.StartTime);
|
||||||
@ -87,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (segmentDuration <= 110)
|
if (segmentDuration <= 110)
|
||||||
{
|
{
|
||||||
if (PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if (PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
convertType |= PatternType.ForceNotStack;
|
convertType |= PatternType.ForceNotStack;
|
||||||
else
|
else
|
||||||
convertType &= ~PatternType.ForceNotStack;
|
convertType &= ~PatternType.ForceNotStack;
|
||||||
@ -135,12 +134,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int usableColumns = AvailableColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
||||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
for (int i = 0; i < noteCount - usableColumns; i++)
|
for (int i = 0; i < noteCount - usableColumns; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,10 +171,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastColumn = nextColumn;
|
int lastColumn = nextColumn;
|
||||||
@ -183,7 +182,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
while (nextColumn == lastColumn)
|
while (nextColumn == lastColumn)
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
lastColumn = nextColumn;
|
lastColumn = nextColumn;
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
@ -221,7 +220,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Check if we're at the borders of the stage, and invert the pattern if so
|
// Check if we're at the borders of the stage, and invert the pattern if so
|
||||||
if (increasing)
|
if (increasing)
|
||||||
{
|
{
|
||||||
if (column >= AvailableColumns - 1)
|
if (column >= TotalColumns - 1)
|
||||||
{
|
{
|
||||||
increasing = false;
|
increasing = false;
|
||||||
column--;
|
column--;
|
||||||
@ -259,8 +258,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
bool legacy = AvailableColumns >= 4 && AvailableColumns <= 8;
|
bool legacy = TotalColumns >= 4 && TotalColumns <= 8;
|
||||||
int interval = Random.Next(1, AvailableColumns - (legacy ? 1 : 0));
|
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
for (int i = 0; i <= repeatCount; i++)
|
||||||
@ -268,15 +267,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
|
|
||||||
nextColumn += interval;
|
nextColumn += interval;
|
||||||
if (nextColumn >= AvailableColumns - RandomStart)
|
if (nextColumn >= TotalColumns - RandomStart)
|
||||||
nextColumn = nextColumn - AvailableColumns - RandomStart + (legacy ? 1 : 0);
|
nextColumn = nextColumn - TotalColumns - RandomStart + (legacy ? 1 : 0);
|
||||||
nextColumn += RandomStart;
|
nextColumn += RandomStart;
|
||||||
|
|
||||||
// If we're in 2K, let's not add many consecutive doubles
|
// If we're in 2K, let's not add many consecutive doubles
|
||||||
if (AvailableColumns > 2)
|
if (TotalColumns > 2)
|
||||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||||
|
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +297,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// □ - □ □
|
// □ - □ □
|
||||||
// ■ - ■ ■
|
// ■ - ■ ■
|
||||||
|
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p2 = 0;
|
p2 = 0;
|
||||||
@ -351,19 +350,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int columnRepeat = Math.Min(repeatCount, AvailableColumns);
|
int columnRepeat = Math.Min(repeatCount, TotalColumns);
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < columnRepeat; i++)
|
for (int i = 0; i < columnRepeat; i++)
|
||||||
{
|
{
|
||||||
while (pattern.ColumnHasObject(nextColumn))
|
while (pattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn, startTime, endTime);
|
addToPattern(pattern, nextColumn, startTime, endTime);
|
||||||
startTime += segmentDuration;
|
startTime += segmentDuration;
|
||||||
@ -388,10 +387,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < AvailableColumns)
|
if ((convertType & PatternType.ForceNotStack) > 0 && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
{
|
{
|
||||||
while (PreviousPattern.ColumnHasObject(holdColumn))
|
while (PreviousPattern.ColumnHasObject(holdColumn))
|
||||||
holdColumn = Random.Next(RandomStart, AvailableColumns);
|
holdColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the hold note
|
// Create the hold note
|
||||||
@ -401,13 +400,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
noteCount = GetRandomNoteCount(0.63, 0);
|
noteCount = GetRandomNoteCount(0.63, 0);
|
||||||
else if (ConversionDifficulty > 4)
|
else if (ConversionDifficulty > 4)
|
||||||
noteCount = GetRandomNoteCount(AvailableColumns < 6 ? 0.12 : 0.45, 0);
|
noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0);
|
||||||
else if (ConversionDifficulty > 2.5)
|
else if (ConversionDifficulty > 2.5)
|
||||||
noteCount = GetRandomNoteCount(AvailableColumns < 6 ? 0 : 0.24, 0);
|
noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0);
|
||||||
noteCount = Math.Min(AvailableColumns - 1, noteCount);
|
noteCount = Math.Min(TotalColumns - 1, noteCount);
|
||||||
|
|
||||||
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
||||||
int nextColumn = Random.Next(RandomStart, AvailableColumns);
|
int nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
|
|
||||||
var rowPattern = new Pattern();
|
var rowPattern = new Pattern();
|
||||||
for (int i = 0; i <= repeatCount; i++)
|
for (int i = 0; i <= repeatCount; i++)
|
||||||
@ -417,7 +416,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
for (int j = 0; j < noteCount; j++)
|
for (int j = 0; j < noteCount; j++)
|
||||||
{
|
{
|
||||||
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
while (rowPattern.ColumnHasObject(nextColumn) || nextColumn == holdColumn)
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
addToPattern(rowPattern, nextColumn, startTime, startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -16,8 +15,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
private readonly double endTime;
|
private readonly double endTime;
|
||||||
|
|
||||||
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns)
|
public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap)
|
||||||
: base(random, hitObject, beatmap, availableColumns, new Pattern())
|
: base(random, hitObject, beatmap, new Pattern())
|
||||||
{
|
{
|
||||||
var endtimeData = HitObject as IHasEndTime;
|
var endtimeData = HitObject as IHasEndTime;
|
||||||
|
|
||||||
@ -30,14 +29,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
bool generateHold = endTime - HitObject.StartTime >= 100;
|
bool generateHold = endTime - HitObject.StartTime >= 100;
|
||||||
|
|
||||||
if (AvailableColumns == 8)
|
if (TotalColumns == 8)
|
||||||
{
|
{
|
||||||
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000)
|
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000)
|
||||||
addToPattern(pattern, 0, generateHold);
|
addToPattern(pattern, 0, generateHold);
|
||||||
else
|
else
|
||||||
addToPattern(pattern, getNextRandomColumn(RandomStart), generateHold);
|
addToPattern(pattern, getNextRandomColumn(RandomStart), generateHold);
|
||||||
}
|
}
|
||||||
else if (AvailableColumns > 0)
|
else if (TotalColumns > 0)
|
||||||
addToPattern(pattern, getNextRandomColumn(0), generateHold);
|
addToPattern(pattern, getNextRandomColumn(0), generateHold);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -50,10 +49,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>A random column after <paramref name="start"/>.</returns>
|
/// <returns>A random column after <paramref name="start"/>.</returns>
|
||||||
private int getNextRandomColumn(int start)
|
private int getNextRandomColumn(int start)
|
||||||
{
|
{
|
||||||
int nextColumn = Random.Next(start, AvailableColumns);
|
int nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
|
||||||
while (PreviousPattern.ColumnHasObject(nextColumn))
|
while (PreviousPattern.ColumnHasObject(nextColumn))
|
||||||
nextColumn = Random.Next(start, AvailableColumns);
|
nextColumn = Random.Next(start, TotalColumns);
|
||||||
|
|
||||||
return nextColumn;
|
return nextColumn;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
@ -20,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
private readonly PatternType convertType;
|
private readonly PatternType convertType;
|
||||||
|
|
||||||
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair)
|
||||||
: base(random, hitObject, beatmap, availableColumns, previousPattern)
|
: base(random, hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
|
if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime));
|
||||||
if (density < 0) throw new ArgumentOutOfRangeException(nameof(density));
|
if (density < 0) throw new ArgumentOutOfRangeException(nameof(density));
|
||||||
@ -88,23 +87,23 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Generate a new pattern by copying the last hit objects in reverse-column order
|
// Generate a new pattern by copying the last hit objects in reverse-column order
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
addToPattern(pattern, RandomStart + AvailableColumns - i - 1);
|
addToPattern(pattern, RandomStart + TotalColumns - i - 1);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1
|
||||||
// If we convert to 7K + 1, let's not overload the special key
|
// If we convert to 7K + 1, let's not overload the special key
|
||||||
&& (AvailableColumns != 8 || lastColumn != 0)
|
&& (TotalColumns != 8 || lastColumn != 0)
|
||||||
// Make sure the last column was not the centre column
|
// Make sure the last column was not the centre column
|
||||||
&& (AvailableColumns % 2 == 0 || lastColumn != AvailableColumns / 2))
|
&& (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
|
||||||
{
|
{
|
||||||
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int column = RandomStart + AvailableColumns - lastColumn - 1;
|
int column = RandomStart + TotalColumns - lastColumn - 1;
|
||||||
addToPattern(pattern, column);
|
addToPattern(pattern, column);
|
||||||
|
|
||||||
return pattern;
|
return pattern;
|
||||||
@ -115,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Generate a new pattern by placing on the already filled columns
|
// Generate a new pattern by placing on the already filled columns
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
for (int i = RandomStart; i < AvailableColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
if (PreviousPattern.ColumnHasObject(i))
|
if (PreviousPattern.ColumnHasObject(i))
|
||||||
addToPattern(pattern, i);
|
addToPattern(pattern, i);
|
||||||
|
|
||||||
@ -128,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int targetColumn = lastColumn + 1;
|
int targetColumn = lastColumn + 1;
|
||||||
if (targetColumn == AvailableColumns)
|
if (targetColumn == TotalColumns)
|
||||||
{
|
{
|
||||||
targetColumn = RandomStart;
|
targetColumn = RandomStart;
|
||||||
StairType = PatternType.ReverseStair;
|
StairType = PatternType.ReverseStair;
|
||||||
@ -146,7 +145,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int targetColumn = lastColumn - 1;
|
int targetColumn = lastColumn - 1;
|
||||||
if (targetColumn == RandomStart - 1)
|
if (targetColumn == RandomStart - 1)
|
||||||
{
|
{
|
||||||
targetColumn = AvailableColumns - 1;
|
targetColumn = TotalColumns - 1;
|
||||||
StairType = PatternType.Stair;
|
StairType = PatternType.Stair;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +205,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
|
bool allowStacking = (convertType & PatternType.ForceNotStack) == 0;
|
||||||
|
|
||||||
if (!allowStacking)
|
if (!allowStacking)
|
||||||
noteCount = Math.Min(noteCount, AvailableColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
@ -216,11 +215,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if ((convertType & PatternType.Gathered) > 0)
|
if ((convertType & PatternType.Gathered) > 0)
|
||||||
{
|
{
|
||||||
nextColumn++;
|
nextColumn++;
|
||||||
if (nextColumn == AvailableColumns)
|
if (nextColumn == TotalColumns)
|
||||||
nextColumn = RandomStart;
|
nextColumn = RandomStart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nextColumn = Random.Next(RandomStart, AvailableColumns);
|
nextColumn = Random.Next(RandomStart, TotalColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
@ -268,7 +267,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
bool addToCentre;
|
bool addToCentre;
|
||||||
int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre);
|
int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre);
|
||||||
|
|
||||||
int columnLimit = (AvailableColumns % 2 == 0 ? AvailableColumns : AvailableColumns - 1) / 2;
|
int columnLimit = (TotalColumns % 2 == 0 ? TotalColumns : TotalColumns - 1) / 2;
|
||||||
int nextColumn = Random.Next(RandomStart, columnLimit);
|
int nextColumn = Random.Next(RandomStart, columnLimit);
|
||||||
for (int i = 0; i < noteCount; i++)
|
for (int i = 0; i < noteCount; i++)
|
||||||
{
|
{
|
||||||
@ -278,11 +277,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
// Add normal note
|
// Add normal note
|
||||||
addToPattern(pattern, nextColumn);
|
addToPattern(pattern, nextColumn);
|
||||||
// Add mirrored note
|
// Add mirrored note
|
||||||
addToPattern(pattern, RandomStart + AvailableColumns - nextColumn - 1);
|
addToPattern(pattern, RandomStart + TotalColumns - nextColumn - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addToCentre)
|
if (addToCentre)
|
||||||
addToPattern(pattern, AvailableColumns / 2);
|
addToPattern(pattern, TotalColumns / 2);
|
||||||
|
|
||||||
if (RandomStart > 0 && hasSpecialColumn)
|
if (RandomStart > 0 && hasSpecialColumn)
|
||||||
addToPattern(pattern, 0);
|
addToPattern(pattern, 0);
|
||||||
@ -300,7 +299,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>The amount of notes to be generated.</returns>
|
/// <returns>The amount of notes to be generated.</returns>
|
||||||
private int getRandomNoteCount(double p2, double p3, double p4, double p5)
|
private int getRandomNoteCount(double p2, double p3, double p4, double p5)
|
||||||
{
|
{
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
p2 = 0;
|
p2 = 0;
|
||||||
@ -348,7 +347,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
if ((convertType & PatternType.ForceNotStack) > 0)
|
if ((convertType & PatternType.ForceNotStack) > 0)
|
||||||
return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3);
|
return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3);
|
||||||
|
|
||||||
switch (AvailableColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
centreProbability = 0;
|
centreProbability = 0;
|
||||||
@ -379,7 +378,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
double centreVal = Random.NextDouble();
|
double centreVal = Random.NextDouble();
|
||||||
int noteCount = GetRandomNoteCount(p2, p3);
|
int noteCount = GetRandomNoteCount(p2, p3);
|
||||||
|
|
||||||
addToCentre = AvailableColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability;
|
addToCentre = TotalColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability;
|
||||||
return noteCount;
|
return noteCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,16 +25,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly FastRandom Random;
|
protected readonly FastRandom Random;
|
||||||
|
|
||||||
protected PatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
: base(hitObject, beatmap, availableColumns, previousPattern)
|
: base(hitObject, beatmap, previousPattern)
|
||||||
{
|
{
|
||||||
if (random == null) throw new ArgumentNullException(nameof(random));
|
if (random == null) throw new ArgumentNullException(nameof(random));
|
||||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
|
||||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||||
|
|
||||||
Random = random;
|
Random = random;
|
||||||
RandomStart = AvailableColumns == 8 ? 1 : 0;
|
RandomStart = TotalColumns == 8 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,14 +44,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>The column.</returns>
|
/// <returns>The column.</returns>
|
||||||
protected int GetColumn(float position, bool allowSpecial = false)
|
protected int GetColumn(float position, bool allowSpecial = false)
|
||||||
{
|
{
|
||||||
if (allowSpecial && AvailableColumns == 8)
|
if (allowSpecial && TotalColumns == 8)
|
||||||
{
|
{
|
||||||
const float local_x_divisor = 512f / 7;
|
const float local_x_divisor = 512f / 7;
|
||||||
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
return MathHelper.Clamp((int)Math.Floor(position / local_x_divisor), 0, 6) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
float localXDivisor = 512f / AvailableColumns;
|
float localXDivisor = 512f / TotalColumns;
|
||||||
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, AvailableColumns - 1);
|
return MathHelper.Clamp((int)Math.Floor(position / localXDivisor), 0, TotalColumns - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
||||||
@ -12,11 +11,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class PatternGenerator
|
internal abstract class PatternGenerator
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The number of columns available to create the pattern.
|
|
||||||
/// </summary>
|
|
||||||
protected readonly int AvailableColumns;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last pattern.
|
/// The last pattern.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -30,19 +24,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The beatmap which <see cref="HitObject"/> is a part of.
|
/// The beatmap which <see cref="HitObject"/> is a part of.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly Beatmap Beatmap;
|
protected readonly ManiaBeatmap Beatmap;
|
||||||
|
|
||||||
protected PatternGenerator(HitObject hitObject, Beatmap beatmap, int availableColumns, Pattern previousPattern)
|
protected readonly int TotalColumns;
|
||||||
|
|
||||||
|
protected PatternGenerator(HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern)
|
||||||
{
|
{
|
||||||
if (hitObject == null) throw new ArgumentNullException(nameof(hitObject));
|
if (hitObject == null) throw new ArgumentNullException(nameof(hitObject));
|
||||||
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
if (beatmap == null) throw new ArgumentNullException(nameof(beatmap));
|
||||||
if (availableColumns <= 0) throw new ArgumentOutOfRangeException(nameof(availableColumns));
|
|
||||||
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern));
|
||||||
|
|
||||||
HitObject = hitObject;
|
HitObject = hitObject;
|
||||||
Beatmap = beatmap;
|
Beatmap = beatmap;
|
||||||
AvailableColumns = availableColumns;
|
|
||||||
PreviousPattern = previousPattern;
|
PreviousPattern = previousPattern;
|
||||||
|
|
||||||
|
TotalColumns = Beatmap.TotalColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
18
osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
Normal file
18
osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines properties for each stage in a <see cref="ManiaPlayfield"/>.
|
||||||
|
/// </summary>
|
||||||
|
public struct StageDefinition
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The number of <see cref="Column"/>s which this stage contains.
|
||||||
|
/// </summary>
|
||||||
|
public int Columns;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania
|
namespace osu.Game.Rulesets.Mania
|
||||||
{
|
{
|
||||||
@ -18,6 +17,6 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) => 0;
|
public override double Calculate(Dictionary<string, double> categoryDifficulty = null) => 0;
|
||||||
|
|
||||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, (int)Math.Max(1, Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize)));
|
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter(Beatmap beatmap) => new ManiaBeatmapConverter(true, beatmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Replays;
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
@ -96,21 +97,30 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
|
|
||||||
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
public void ApplyToRulesetContainer(RulesetContainer<ManiaHitObject> rulesetContainer)
|
||||||
{
|
{
|
||||||
int availableColumns = ((ManiaRulesetContainer)rulesetContainer).AvailableColumns;
|
int availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
|
||||||
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
|
||||||
|
|
||||||
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
rulesetContainer.Objects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class ManiaKeyMod : Mod
|
public abstract class ManiaKeyMod : Mod, IApplicableMod, IApplicableToBeatmapConverter<ManiaHitObject>
|
||||||
{
|
{
|
||||||
// TODO: implement using the IApplicable interface. Haven't done so yet because KeyCount isn't even hooked up at the moment.
|
|
||||||
|
|
||||||
public override string ShortenedName => Name;
|
public override string ShortenedName => Name;
|
||||||
public abstract int KeyCount { get; }
|
public abstract int KeyCount { get; }
|
||||||
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
|
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
|
public void ApplyToBeatmapConverter(BeatmapConverter<ManiaHitObject> beatmapConverter)
|
||||||
|
{
|
||||||
|
var mbc = (ManiaBeatmapConverter)beatmapConverter;
|
||||||
|
|
||||||
|
// Although this can work, for now let's not allow keymods for mania-specific beatmaps
|
||||||
|
if (mbc.IsForCurrentRuleset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mbc.TargetColumns = KeyCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ManiaModKey1 : ManiaKeyMod
|
public class ManiaModKey1 : ManiaKeyMod
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
@ -28,11 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
{
|
{
|
||||||
public class ManiaRulesetContainer : ScrollingRulesetContainer<ManiaPlayfield, ManiaHitObject>
|
public class ManiaRulesetContainer : ScrollingRulesetContainer<ManiaPlayfield, ManiaHitObject>
|
||||||
{
|
{
|
||||||
/// <summary>
|
public new ManiaBeatmap Beatmap => (ManiaBeatmap)base.Beatmap;
|
||||||
/// The number of columns which the <see cref="ManiaPlayfield"/> should display, and which
|
|
||||||
/// the beatmap converter will attempt to convert beatmaps to use.
|
|
||||||
/// </summary>
|
|
||||||
public int AvailableColumns { get; private set; }
|
|
||||||
|
|
||||||
public IEnumerable<DrawableBarLine> BarLines;
|
public IEnumerable<DrawableBarLine> BarLines;
|
||||||
|
|
||||||
@ -73,7 +68,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
BarLines.ForEach(Playfield.Add);
|
BarLines.ForEach(Playfield.Add);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(AvailableColumns)
|
protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.TotalColumns)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -81,27 +76,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
|
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
|
||||||
|
|
||||||
public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, AvailableColumns);
|
public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Beatmap.TotalColumns);
|
||||||
|
|
||||||
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter()
|
protected override BeatmapConverter<ManiaHitObject> CreateBeatmapConverter() => new ManiaBeatmapConverter(IsForCurrentRuleset, WorkingBeatmap.Beatmap);
|
||||||
{
|
|
||||||
if (IsForCurrentRuleset)
|
|
||||||
AvailableColumns = (int)Math.Max(1, Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.CircleSize));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float percentSliderOrSpinner = (float)WorkingBeatmap.Beatmap.HitObjects.Count(h => h is IHasEndTime) / WorkingBeatmap.Beatmap.HitObjects.Count;
|
|
||||||
if (percentSliderOrSpinner < 0.2)
|
|
||||||
AvailableColumns = 7;
|
|
||||||
else if (percentSliderOrSpinner < 0.3 || Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.CircleSize) >= 5)
|
|
||||||
AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) > 5 ? 7 : 6;
|
|
||||||
else if (percentSliderOrSpinner > 0.6)
|
|
||||||
AvailableColumns = Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) > 4 ? 5 : 4;
|
|
||||||
else
|
|
||||||
AvailableColumns = Math.Max(4, Math.Min((int)Math.Round(WorkingBeatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty) + 1, 7));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ManiaBeatmapConverter(IsForCurrentRuleset, AvailableColumns);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
protected override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
||||||
{
|
{
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Beatmaps\StageDefinition.cs" />
|
||||||
|
<Compile Include="Beatmaps\ManiaBeatmap.cs" />
|
||||||
<Compile Include="Beatmaps\Patterns\Legacy\EndTimeObjectPatternGenerator.cs" />
|
<Compile Include="Beatmaps\Patterns\Legacy\EndTimeObjectPatternGenerator.cs" />
|
||||||
<Compile Include="Beatmaps\Patterns\Legacy\DistanceObjectPatternGenerator.cs" />
|
<Compile Include="Beatmaps\Patterns\Legacy\DistanceObjectPatternGenerator.cs" />
|
||||||
<Compile Include="Beatmaps\Patterns\Legacy\PatternGenerator.cs" />
|
<Compile Include="Beatmaps\Patterns\Legacy\PatternGenerator.cs" />
|
||||||
|
@ -158,14 +158,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
protected override void UpdateCurrentState(ArmedState state)
|
protected override void UpdateCurrentState(ArmedState state)
|
||||||
{
|
{
|
||||||
Ball.FadeIn();
|
Ball.FadeIn();
|
||||||
|
Ball.ScaleTo(HitObject.Scale);
|
||||||
|
|
||||||
using (BeginDelayedSequence(slider.Duration, true))
|
using (BeginDelayedSequence(slider.Duration, true))
|
||||||
{
|
{
|
||||||
Body.FadeOut(160);
|
const float fade_out_time = 450;
|
||||||
Ball.FadeOut(160);
|
|
||||||
|
|
||||||
this.FadeOut(800)
|
// intentionally pile on an extra FadeOut to make it happen much faster.
|
||||||
.Expire();
|
Ball.FadeOut(fade_out_time / 4, Easing.Out);
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ArmedState.Hit:
|
||||||
|
Ball.ScaleTo(HitObject.Scale * 1.4f, fade_out_time, Easing.Out);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.FadeOut(fade_out_time, Easing.OutQuint).Expire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly Slider slider;
|
private readonly Slider slider;
|
||||||
private readonly Box follow;
|
public readonly Box FollowCircle;
|
||||||
private readonly Box ball;
|
private readonly Box ball;
|
||||||
|
|
||||||
public SliderBall(Slider slider)
|
public SliderBall(Slider slider)
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
follow = new Box
|
FollowCircle = new Box
|
||||||
{
|
{
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -101,11 +101,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
// If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position.
|
// If the current time is between the start and end of the slider, we should track mouse input regardless of the cursor position.
|
||||||
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos);
|
public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => canCurrentlyTrack || base.ReceiveMouseInputAt(screenSpacePos);
|
||||||
|
|
||||||
public override void ClearTransforms(bool propagateChildren = false, string targetMember = null)
|
public override void ClearTransformsAfter(double time, bool propagateChildren = false, string targetMember = null)
|
||||||
{
|
{
|
||||||
// Consider the case of rewinding - children's transforms are handled internally, so propagating down
|
// Consider the case of rewinding - children's transforms are handled internally, so propagating down
|
||||||
// any further will cause weirdness with the Tracking bool below. Let's not propagate further at this point.
|
// any further will cause weirdness with the Tracking bool below. Let's not propagate further at this point.
|
||||||
base.ClearTransforms(false, targetMember);
|
base.ClearTransformsAfter(time, false, targetMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool tracking;
|
private bool tracking;
|
||||||
@ -118,8 +118,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
follow.ScaleTo(tracking ? 2.8f : 1, 300, Easing.OutQuint);
|
FollowCircle.ScaleTo(tracking ? 2.8f : 1, 300, Easing.OutQuint);
|
||||||
follow.FadeTo(tracking ? 0.2f : 0, 300, Easing.OutQuint);
|
FollowCircle.FadeTo(tracking ? 0.2f : 0, 300, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,12 +129,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
|
if (Time.Current < slider.EndTime)
|
||||||
|
{
|
||||||
// Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position.
|
// Make sure to use the base version of ReceiveMouseInputAt so that we correctly check the position.
|
||||||
Tracking = canCurrentlyTrack
|
Tracking = canCurrentlyTrack
|
||||||
&& lastState != null
|
&& lastState != null
|
||||||
&& base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position)
|
&& base.ReceiveMouseInputAt(lastState.Mouse.NativeState.Position)
|
||||||
&& ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
|
&& ((Parent as DrawableSlider)?.OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateProgress(double progress, int repeat)
|
public void UpdateProgress(double progress, int repeat)
|
||||||
{
|
{
|
||||||
|
@ -39,12 +39,12 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <returns>The converted Beatmap.</returns>
|
/// <returns>The converted Beatmap.</returns>
|
||||||
protected virtual Beatmap<T> ConvertBeatmap(Beatmap original)
|
protected virtual Beatmap<T> ConvertBeatmap(Beatmap original)
|
||||||
{
|
{
|
||||||
return new Beatmap<T>
|
var beatmap = CreateBeatmap();
|
||||||
{
|
beatmap.BeatmapInfo = original.BeatmapInfo;
|
||||||
BeatmapInfo = original.BeatmapInfo,
|
beatmap.ControlPointInfo = original.ControlPointInfo;
|
||||||
ControlPointInfo = original.ControlPointInfo,
|
beatmap.HitObjects = original.HitObjects.SelectMany(h => convert(h, original)).ToList();
|
||||||
HitObjects = original.HitObjects.SelectMany(h => convert(h, original)).ToList()
|
|
||||||
};
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -78,6 +78,11 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract IEnumerable<Type> ValidConversionTypes { get; }
|
protected abstract IEnumerable<Type> ValidConversionTypes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates the <see cref="Beatmap{T}"/> that will be returned by this <see cref="BeatmapProcessor{T}"/>.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual Beatmap<T> CreateBeatmap() => new Beatmap<T>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs the conversion of a hit object.
|
/// Performs the conversion of a hit object.
|
||||||
/// This method is generally executed sequentially for all objects in a beatmap.
|
/// This method is generally executed sequentially for all objects in a beatmap.
|
||||||
|
@ -64,24 +64,24 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// <returns>The timing control point.</returns>
|
/// <returns>The timing control point.</returns>
|
||||||
public TimingControlPoint TimingPointAt(double time) => binarySearch(TimingPoints, time, TimingPoints.FirstOrDefault());
|
public TimingControlPoint TimingPointAt(double time) => binarySearch(TimingPoints, time, TimingPoints.FirstOrDefault());
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the maximum BPM represented by any timing control point.
|
/// Finds the maximum BPM represented by any timing control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
public double BPMMaximum =>
|
public double BPMMaximum =>
|
||||||
60000 / (TimingPoints.OrderBy(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
60000 / (TimingPoints.OrderBy(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the minimum BPM represented by any timing control point.
|
/// Finds the minimum BPM represented by any timing control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
public double BPMMinimum =>
|
public double BPMMinimum =>
|
||||||
60000 / (TimingPoints.OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
60000 / (TimingPoints.OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
||||||
|
|
||||||
[JsonIgnore]
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the mode BPM (most common BPM) represented by the control points.
|
/// Finds the mode BPM (most common BPM) represented by the control points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
public double BPMMode =>
|
public double BPMMode =>
|
||||||
60000 / (TimingPoints.GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
60000 / (TimingPoints.GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength;
|
||||||
|
|
||||||
|
@ -73,8 +73,6 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool pending;
|
|
||||||
|
|
||||||
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
|
||||||
{
|
{
|
||||||
if ((invalidation & Invalidation.DrawSize) > 0)
|
if ((invalidation & Invalidation.DrawSize) > 0)
|
||||||
|
@ -9,11 +9,11 @@ using Newtonsoft.Json.Linq;
|
|||||||
namespace osu.Game.IO.Serialization.Converters
|
namespace osu.Game.IO.Serialization.Converters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A type of <see cref="JsonConverter"/> that serializes a <see cref="List<T>"/> alongside
|
/// A type of <see cref="JsonConverter"/> that serializes a <see cref="List{T}"/> alongside
|
||||||
/// a lookup table for the types contained. The lookup table is used in deserialization to
|
/// a lookup table for the types contained. The lookup table is used in deserialization to
|
||||||
/// reconstruct the objects with their original types.
|
/// reconstruct the objects with their original types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of objects contained in the <see cref="List<T>"/> this attribute is attached to.</typeparam>
|
/// <typeparam name="T">The type of objects contained in the <see cref="List{T}"/> this attribute is attached to.</typeparam>
|
||||||
public class TypedListConverter<T> : JsonConverter
|
public class TypedListConverter<T> : JsonConverter
|
||||||
{
|
{
|
||||||
private readonly bool requiresTypeVersion;
|
private readonly bool requiresTypeVersion;
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using OpenTK;
|
using OpenTK;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -16,7 +15,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
{
|
{
|
||||||
public abstract class DrawableProfileScore : DrawableProfileRow
|
public abstract class DrawableProfileScore : DrawableProfileRow
|
||||||
{
|
{
|
||||||
private readonly FillFlowContainer metadata;
|
|
||||||
private readonly ScoreModsContainer modsContainer;
|
private readonly ScoreModsContainer modsContainer;
|
||||||
protected readonly Score Score;
|
protected readonly Score Score;
|
||||||
|
|
||||||
|
22
osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs
Normal file
22
osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) 2007-2017 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.Objects;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interface for a <see cref="Mod"/> that applies changes to a <see cref="BeatmapConverter{TObject}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TObject">The type of converted <see cref="HitObject"/>.</typeparam>
|
||||||
|
public interface IApplicableToBeatmapConverter<TObject>
|
||||||
|
where TObject : HitObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Applies this <see cref="Mod"/> to a <see cref="BeatmapConverter{TObject}"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="beatmapConverter">The <see cref="BeatmapConverter{TObject}"/> to apply to.</param>
|
||||||
|
void ApplyToBeatmapConverter(BeatmapConverter<TObject> beatmapConverter);
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Applies this <see cref="IApplicableToDrawableHitObjects"/> to a list of <see cref="DrawableHitObject"/>s.
|
/// Applies this <see cref="IApplicableToDrawableHitObjects"/> to a list of <see cref="DrawableHitObject"/>s.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="drawable">The list of <see cref="DrawableHitObject"/>s to apply to.</param>
|
/// <param name="drawables">The list of <see cref="DrawableHitObject"/>s to apply to.</param>
|
||||||
void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables);
|
void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,6 +176,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
if (!converter.CanConvert(workingBeatmap.Beatmap))
|
if (!converter.CanConvert(workingBeatmap.Beatmap))
|
||||||
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter}).");
|
throw new BeatmapInvalidForRulesetException($"{nameof(Beatmap)} can not be converted for the current ruleset (converter: {converter}).");
|
||||||
|
|
||||||
|
// Apply conversion adjustments before converting
|
||||||
|
foreach (var mod in Mods.OfType<IApplicableToBeatmapConverter<TObject>>())
|
||||||
|
mod.ApplyToBeatmapConverter(converter);
|
||||||
|
|
||||||
// Convert the beatmap
|
// Convert the beatmap
|
||||||
Beatmap = converter.Convert(workingBeatmap.Beatmap);
|
Beatmap = converter.Convert(workingBeatmap.Beatmap);
|
||||||
|
|
||||||
|
@ -101,8 +101,6 @@ namespace osu.Game.Screens
|
|||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Shader currentLoadTarget;
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
@ -20,6 +20,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
@ -86,6 +87,8 @@ namespace osu.Game.Screens.Select
|
|||||||
public OsuSpriteText ArtistLabel { get; private set; }
|
public OsuSpriteText ArtistLabel { get; private set; }
|
||||||
public FillFlowContainer MapperContainer { get; private set; }
|
public FillFlowContainer MapperContainer { get; private set; }
|
||||||
public FillFlowContainer InfoLabelContainer { get; private set; }
|
public FillFlowContainer InfoLabelContainer { get; private set; }
|
||||||
|
private UnicodeBindableString titleBinding;
|
||||||
|
private UnicodeBindableString artistBinding;
|
||||||
|
|
||||||
public BufferedWedgeInfo(WorkingBeatmap working)
|
public BufferedWedgeInfo(WorkingBeatmap working)
|
||||||
{
|
{
|
||||||
@ -93,7 +96,7 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(LocalisationEngine localisation)
|
||||||
{
|
{
|
||||||
var beatmapInfo = working.BeatmapInfo;
|
var beatmapInfo = working.BeatmapInfo;
|
||||||
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata();
|
||||||
@ -102,6 +105,9 @@ namespace osu.Game.Screens.Select
|
|||||||
CacheDrawnFrameBuffer = true;
|
CacheDrawnFrameBuffer = true;
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
titleBinding = localisation.GetUnicodePreference(metadata.TitleUnicode, metadata.Title);
|
||||||
|
artistBinding = localisation.GetUnicodePreference(metadata.ArtistUnicode, metadata.Artist);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
// We will create the white-to-black gradient by modulating transparency and having
|
// We will create the white-to-black gradient by modulating transparency and having
|
||||||
@ -167,13 +173,11 @@ namespace osu.Game.Screens.Select
|
|||||||
TitleLabel = new OsuSpriteText
|
TitleLabel = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = @"Exo2.0-MediumItalic",
|
Font = @"Exo2.0-MediumItalic",
|
||||||
Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title,
|
|
||||||
TextSize = 28,
|
TextSize = 28,
|
||||||
},
|
},
|
||||||
ArtistLabel = new OsuSpriteText
|
ArtistLabel = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = @"Exo2.0-MediumItalic",
|
Font = @"Exo2.0-MediumItalic",
|
||||||
Text = metadata.Artist,
|
|
||||||
TextSize = 17,
|
TextSize = 17,
|
||||||
},
|
},
|
||||||
MapperContainer = new FillFlowContainer
|
MapperContainer = new FillFlowContainer
|
||||||
@ -193,6 +197,15 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
artistBinding.ValueChanged += value => setMetadata(metadata.Source);
|
||||||
|
artistBinding.TriggerChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMetadata(string source)
|
||||||
|
{
|
||||||
|
ArtistLabel.Text = artistBinding.Value;
|
||||||
|
TitleLabel.Text = string.IsNullOrEmpty(source) ? titleBinding.Value : source + " — " + titleBinding.Value;
|
||||||
|
ForceRedraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
private InfoLabel[] getInfoLabels()
|
private InfoLabel[] getInfoLabels()
|
||||||
|
@ -10,8 +10,6 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CarouselGroup : CarouselItem
|
public class CarouselGroup : CarouselItem
|
||||||
{
|
{
|
||||||
private readonly List<CarouselItem> items;
|
|
||||||
|
|
||||||
protected override DrawableCarouselItem CreateDrawableRepresentation() => null;
|
protected override DrawableCarouselItem CreateDrawableRepresentation() => null;
|
||||||
|
|
||||||
public IReadOnlyList<CarouselItem> Children => InternalChildren;
|
public IReadOnlyList<CarouselItem> Children => InternalChildren;
|
||||||
|
@ -31,8 +31,6 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
|
|
||||||
private readonly BeatmapSetInfo beatmapSet;
|
private readonly BeatmapSetInfo beatmapSet;
|
||||||
|
|
||||||
private readonly FillFlowContainer difficultyIcons;
|
|
||||||
|
|
||||||
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
|
public DrawableCarouselBeatmapSet(CarouselBeatmapSet set)
|
||||||
: base(set)
|
: base(set)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
private readonly SpriteIcon icon;
|
private readonly SpriteIcon icon;
|
||||||
|
|
||||||
public Action Action;
|
public new Action Action;
|
||||||
|
|
||||||
public RetryButton()
|
public RetryButton()
|
||||||
{
|
{
|
||||||
|
@ -313,6 +313,7 @@
|
|||||||
<Compile Include="Overlays\Settings\Sections\Maintenance\DeleteAllBeatmapsDialog.cs" />
|
<Compile Include="Overlays\Settings\Sections\Maintenance\DeleteAllBeatmapsDialog.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableFailOverride.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableMod.cs" />
|
||||||
|
<Compile Include="Rulesets\Mods\IApplicableToBeatmapConverter.cs" />
|
||||||
<Compile Include="Rulesets\Mods\IApplicableToDrawableHitObject.cs" />
|
<Compile Include="Rulesets\Mods\IApplicableToDrawableHitObject.cs" />
|
||||||
<Compile Include="Rulesets\UI\Scrolling\ScrollingDirection.cs" />
|
<Compile Include="Rulesets\UI\Scrolling\ScrollingDirection.cs" />
|
||||||
<Compile Include="Rulesets\UI\Scrolling\ScrollingHitObjectContainer.cs" />
|
<Compile Include="Rulesets\UI\Scrolling\ScrollingHitObjectContainer.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user