1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 04:07:25 +08:00

Merge branch 'master' into colours-for-judgements

This commit is contained in:
Dan Balasescu 2018-04-04 15:02:03 +09:00 committed by GitHub
commit b5d7a5df00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 146 additions and 122 deletions

@ -1 +1 @@
Subproject commit 85b3494117ccef1b396b70957e1cffaba06e2b54
Subproject commit 6852878ce30e1bfde301282563d09c7927d9106c

View File

@ -30,10 +30,10 @@ namespace osu.Game.Rulesets.Catch.UI
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
ScaledContent.Anchor = Anchor.BottomLeft;
ScaledContent.Origin = Anchor.BottomLeft;
base.Content.Anchor = Anchor.BottomLeft;
base.Content.Origin = Anchor.BottomLeft;
ScaledContent.AddRange(new Drawable[]
base.Content.AddRange(new Drawable[]
{
explodingFruitContainer = new Container
{

View File

@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModAutoplay : ModAutoplay<OsuHitObject>
{
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModSpunOut) }).ToArray();
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).Append(typeof(OsuModSpunOut)).ToArray();
protected override Score CreateReplayScore(Beatmap<OsuHitObject> beatmap)
{

View File

@ -9,6 +9,6 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModNoFail : ModNoFail
{
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
}
}

View File

@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModRelax : ModRelax
{
public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things.";
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
}
}

View File

@ -9,6 +9,6 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public class OsuModSuddenDeath : ModSuddenDeath
{
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
}
}

View File

@ -92,17 +92,17 @@ namespace osu.Game.Rulesets.Osu.Replays
if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Miss), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh) > endTime + h.HitWindows.HalfWindowFor(HitResult.Meh) + 50)
else if (h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good) > endTime + h.HitWindows.HalfWindowFor(HitResult.Good) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Meh), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new OsuReplayFrame(endTime + h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(prev.StackedEndPosition.X, prev.StackedEndPosition.Y)));
if (!(h is Spinner)) AddFrameToReplay(new OsuReplayFrame(h.StartTime - h.HitWindows.HalfWindowFor(HitResult.Good), new Vector2(h.StackedPosition.X, h.StackedPosition.Y)));
}
}

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Replays
{
new ReplayState<OsuAction>
{
Mouse = new ReplayMouseState(ToScreenSpace(Position ?? Vector2.Zero)),
Mouse = new ReplayMouseState(GamefieldToScreenSpace(Position ?? Vector2.Zero)),
PressedActions = CurrentFrame.Actions
}
};

View File

@ -122,7 +122,7 @@ namespace osu.Game.Tests.Visual
Direction = direction;
Padding = new MarginPadding(2);
ScaledContent.Masking = true;
Content.Masking = true;
AddInternal(new Box
{

View File

@ -16,7 +16,7 @@ namespace osu.Game.Beatmaps.Formats
public TOutput Decode(StreamReader primaryStream, params StreamReader[] otherStreams)
{
var output = CreateTemplateObject();
foreach (StreamReader stream in new[] { primaryStream }.Concat(otherStreams))
foreach (StreamReader stream in otherStreams.Prepend(primaryStream))
ParseStreamInto(stream, output);
return output;
}

View File

@ -81,13 +81,13 @@ namespace osu.Game.Beatmaps.Formats
handleDifficulty(line);
return;
case Section.Events:
handleEvents(line);
handleEvent(line);
return;
case Section.TimingPoints:
handleTimingPoints(line);
handleTimingPoint(line);
return;
case Section.HitObjects:
handleHitObjects(line);
handleHitObject(line);
return;
}
@ -246,7 +246,7 @@ namespace osu.Game.Beatmaps.Formats
}
}
private void handleEvents(string line)
private void handleEvent(string line)
{
string[] split = line.Split(',');
@ -275,93 +275,99 @@ namespace osu.Game.Beatmaps.Formats
}
}
private void handleTimingPoints(string line)
private void handleTimingPoint(string line)
{
string[] split = line.Split(',');
double time = getOffsetTime(double.Parse(split[0].Trim(), NumberFormatInfo.InvariantInfo));
double beatLength = double.Parse(split[1].Trim(), NumberFormatInfo.InvariantInfo);
double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1;
TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple;
if (split.Length >= 3)
timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)int.Parse(split[2]);
LegacySampleBank sampleSet = defaultSampleBank;
if (split.Length >= 4)
sampleSet = (LegacySampleBank)int.Parse(split[3]);
//SampleBank sampleBank = SampleBank.Default;
//if (split.Length >= 5)
// sampleBank = (SampleBank)int.Parse(split[4]);
int sampleVolume = defaultSampleVolume;
if (split.Length >= 6)
sampleVolume = int.Parse(split[5]);
bool timingChange = true;
if (split.Length >= 7)
timingChange = split[6][0] == '1';
bool kiaiMode = false;
bool omitFirstBarSignature = false;
if (split.Length >= 8)
try
{
int effectFlags = int.Parse(split[7]);
kiaiMode = (effectFlags & 1) > 0;
omitFirstBarSignature = (effectFlags & 8) > 0;
}
string[] split = line.Split(',');
string stringSampleSet = sampleSet.ToString().ToLower();
if (stringSampleSet == @"none")
stringSampleSet = @"normal";
double time = getOffsetTime(double.Parse(split[0].Trim(), NumberFormatInfo.InvariantInfo));
double beatLength = double.Parse(split[1].Trim(), NumberFormatInfo.InvariantInfo);
double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1;
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time);
SampleControlPoint samplePoint = beatmap.ControlPointInfo.SamplePointAt(time);
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);
TimeSignatures timeSignature = TimeSignatures.SimpleQuadruple;
if (split.Length >= 3)
timeSignature = split[2][0] == '0' ? TimeSignatures.SimpleQuadruple : (TimeSignatures)int.Parse(split[2]);
if (timingChange)
{
beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint
LegacySampleBank sampleSet = defaultSampleBank;
if (split.Length >= 4)
sampleSet = (LegacySampleBank)int.Parse(split[3]);
//SampleBank sampleBank = SampleBank.Default;
//if (split.Length >= 5)
// sampleBank = (SampleBank)int.Parse(split[4]);
int sampleVolume = defaultSampleVolume;
if (split.Length >= 6)
sampleVolume = int.Parse(split[5]);
bool timingChange = true;
if (split.Length >= 7)
timingChange = split[6][0] == '1';
bool kiaiMode = false;
bool omitFirstBarSignature = false;
if (split.Length >= 8)
{
Time = time,
BeatLength = beatLength,
TimeSignature = timeSignature
});
}
int effectFlags = int.Parse(split[7]);
kiaiMode = (effectFlags & 1) > 0;
omitFirstBarSignature = (effectFlags & 8) > 0;
}
if (speedMultiplier != difficultyPoint.SpeedMultiplier)
{
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time);
beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint
{
Time = time,
SpeedMultiplier = speedMultiplier
});
}
string stringSampleSet = sampleSet.ToString().ToLower();
if (stringSampleSet == @"none")
stringSampleSet = @"normal";
if (stringSampleSet != samplePoint.SampleBank || sampleVolume != samplePoint.SampleVolume)
{
beatmap.ControlPointInfo.SamplePoints.Add(new SampleControlPoint
{
Time = time,
SampleBank = stringSampleSet,
SampleVolume = sampleVolume
});
}
DifficultyControlPoint difficultyPoint = beatmap.ControlPointInfo.DifficultyPointAt(time);
SampleControlPoint samplePoint = beatmap.ControlPointInfo.SamplePointAt(time);
EffectControlPoint effectPoint = beatmap.ControlPointInfo.EffectPointAt(time);
if (kiaiMode != effectPoint.KiaiMode || omitFirstBarSignature != effectPoint.OmitFirstBarLine)
{
beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint
if (timingChange)
{
Time = time,
KiaiMode = kiaiMode,
OmitFirstBarLine = omitFirstBarSignature
});
beatmap.ControlPointInfo.TimingPoints.Add(new TimingControlPoint
{
Time = time,
BeatLength = beatLength,
TimeSignature = timeSignature
});
}
if (speedMultiplier != difficultyPoint.SpeedMultiplier)
{
beatmap.ControlPointInfo.DifficultyPoints.RemoveAll(x => x.Time == time);
beatmap.ControlPointInfo.DifficultyPoints.Add(new DifficultyControlPoint
{
Time = time,
SpeedMultiplier = speedMultiplier
});
}
if (stringSampleSet != samplePoint.SampleBank || sampleVolume != samplePoint.SampleVolume)
{
beatmap.ControlPointInfo.SamplePoints.Add(new SampleControlPoint
{
Time = time,
SampleBank = stringSampleSet,
SampleVolume = sampleVolume
});
}
if (kiaiMode != effectPoint.KiaiMode || omitFirstBarSignature != effectPoint.OmitFirstBarLine)
{
beatmap.ControlPointInfo.EffectPoints.Add(new EffectControlPoint
{
Time = time,
KiaiMode = kiaiMode,
OmitFirstBarLine = omitFirstBarSignature
});
}
}
catch (FormatException e)
{
}
}
private void handleHitObjects(string line)
private void handleHitObject(string line)
{
// If the ruleset wasn't specified, assume the osu!standard ruleset.
if (parser == null)

View File

@ -45,7 +45,7 @@ namespace osu.Game.Input.Bindings
};
protected override IEnumerable<Drawable> KeyBindingInputQueue =>
handler == null ? base.KeyBindingInputQueue : new[] { handler }.Concat(base.KeyBindingInputQueue);
handler == null ? base.KeyBindingInputQueue : base.KeyBindingInputQueue.Prepend(handler);
}
public enum GlobalAction

View File

@ -13,9 +13,9 @@ namespace osu.Game.Input.Handlers
public abstract class ReplayInputHandler : InputHandler
{
/// <summary>
/// A function provided to convert replay coordinates from gamefield to screen space.
/// A function that converts coordinates from gamefield to screen space.
/// </summary>
public Func<Vector2, Vector2> ToScreenSpace { protected get; set; }
public Func<Vector2, Vector2> GamefieldToScreenSpace { protected get; set; }
/// <summary>
/// Update the current frame based on an incoming time value.

View File

@ -47,7 +47,7 @@ namespace osu.Game.Overlays.KeyBinding
private FillFlowContainer<KeyButton> buttons;
public IEnumerable<string> FilterTerms => new[] { text.Text }.Concat(bindings.Select(b => b.KeyCombination.ReadableString()));
public IEnumerable<string> FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text);
public KeyBindingRow(object action, IEnumerable<Framework.Input.Bindings.KeyBinding> bindings)
{

View File

@ -128,10 +128,8 @@ namespace osu.Game.Rulesets.Edit
selectionLayer.SelectionFinished += hitObjectMaskLayer.AddSelectionOverlay;
toolboxCollection.Items =
new[] { new RadioButton("Select", () => setCompositionTool(null)) }
.Concat(
CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
)
CompositionTools.Select(t => new RadioButton(t.Name, () => setCompositionTool(t)))
.Prepend(new RadioButton("Select", () => setCompositionTool(null)))
.ToList();
toolboxCollection.Items[0].Select();

View File

@ -290,7 +290,7 @@ namespace osu.Game.Rulesets.UI
base.SetReplay(replay);
if (ReplayInputManager?.ReplayInputHandler != null)
ReplayInputManager.ReplayInputHandler.ToScreenSpace = input => Playfield.ScaledContent.ToScreenSpace(input);
ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace;
}
/// <summary>

View File

@ -1,6 +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;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using OpenTK;
@ -12,13 +13,16 @@ namespace osu.Game.Rulesets.UI
/// </summary>
public class ScalableContainer : Container
{
/// <summary>
/// A function that converts coordinates from gamefield to screen space.
/// </summary>
public Func<Vector2, Vector2> GamefieldToScreenSpace => scaledContent.GamefieldToScreenSpace;
/// <summary>
/// The scaled content.
/// </summary>
public readonly Container ScaledContent;
protected override Container<Drawable> Content => content;
private readonly Container content;
private readonly ScaledContainer scaledContent;
protected override Container<Drawable> Content => scaledContent;
/// <summary>
/// A <see cref="Container"/> which can have its internal coordinate system scaled to a specific size.
@ -31,17 +35,21 @@ namespace osu.Game.Rulesets.UI
/// </param>
public ScalableContainer(float? customWidth = null, float? customHeight = null)
{
AddInternal(ScaledContent = new ScaledContainer
AddInternal(scaledContent = new ScaledContainer
{
CustomWidth = customWidth,
CustomHeight = customHeight,
RelativeSizeAxes = Axes.Both,
Child = content = new Container { RelativeSizeAxes = Axes.Both }
});
}
private class ScaledContainer : Container
{
/// <summary>
/// A function that converts coordinates from gamefield to screen space.
/// </summary>
public Func<Vector2, Vector2> GamefieldToScreenSpace => content.ToScreenSpace;
/// <summary>
/// The value to scale the width of the content to match.
/// If null, <see cref="CustomHeight"/> is used.
@ -54,6 +62,22 @@ namespace osu.Game.Rulesets.UI
/// </summary>
public float? CustomHeight;
private readonly Container content;
protected override Container<Drawable> Content => content;
public ScaledContainer()
{
AddInternal(content = new Container { RelativeSizeAxes = Axes.Both });
}
protected override void Update()
{
base.Update();
content.Scale = sizeScale;
content.Size = Vector2.Divide(Vector2.One, sizeScale);
}
/// <summary>
/// The scale that is required for the size of the content to match <see cref="CustomWidth"/> and <see cref="CustomHeight"/>.
/// </summary>
@ -70,17 +94,6 @@ namespace osu.Game.Rulesets.UI
return Vector2.One;
}
}
/// <summary>
/// Scale the content to the required container size by multiplying by <see cref="sizeScale"/>.
/// </summary>
protected override Vector2 DrawScale => sizeScale * base.DrawScale;
protected override void Update()
{
base.Update();
RelativeChildSize = new Vector2(CustomWidth.HasValue ? sizeScale.X : RelativeChildSize.X, CustomHeight.HasValue ? sizeScale.Y : RelativeChildSize.Y);
}
}
}
}

View File

@ -83,12 +83,19 @@ namespace osu.Game.Screens.Play
private void load(AudioManager audio, APIAccess api, OsuConfigManager config)
{
this.api = api;
WorkingBeatmap working = Beatmap.Value;
if (working is DummyWorkingBeatmap)
{
Exit();
return;
}
sampleRestart = audio.Sample.Get(@"Gameplay/restart");
mouseWheelDisabled = config.GetBindable<bool>(OsuSetting.MouseDisableWheel);
userAudioOffset = config.GetBindable<double>(OsuSetting.AudioOffset);
WorkingBeatmap working = Beatmap.Value;
Beatmap beatmap;
try

View File

@ -150,7 +150,7 @@ namespace osu.Game.Screens.Select
var mods = modSelect.SelectedMods.Value;
if (mods.All(m => m.GetType() != autoType))
{
modSelect.SelectedMods.Value = mods.Concat(new[] { auto });
modSelect.SelectedMods.Value = mods.Append(auto);
removeAutoModOnResume = true;
}
}

View File

@ -92,7 +92,7 @@ namespace osu.Game.Skinning
string lastPiece = filename.Split('/').Last();
var file = source.Files.FirstOrDefault(f =>
string.Equals(hasExtension ? f.Filename : Path.GetFileNameWithoutExtension(f.Filename), lastPiece, StringComparison.InvariantCultureIgnoreCase));
string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), lastPiece, StringComparison.InvariantCultureIgnoreCase));
return file?.FileInfo.StoragePath;
}