1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 14:12:54 +08:00

Merge branch 'master' into maybefix

This commit is contained in:
Dean Herbert 2017-09-11 18:23:00 +09:00 committed by GitHub
commit 18ad0956b4
110 changed files with 1813 additions and 734 deletions

@ -1 +1 @@
Subproject commit 14a33d110e2ed32e3a875bc2acd2bade244ba045
Subproject commit cb48c7bef8c5909472c70e09059ee6ea5bf6fc8a

@ -1 +1 @@
Subproject commit f6042e1cb37cfad6c879d0e1245f7880c7fcd5f5
Subproject commit a4418111f8ed2350a6fd46fe69258884f0757745

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Desktop.Deploy</RootNamespace>
<AssemblyName>osu.Desktop.Deploy</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>

View File

@ -12,50 +12,104 @@ namespace osu.Desktop.Tests.Visual
{
public override string Description => "BeatmapDetails tab of BeatmapDetailArea";
private readonly BeatmapDetails details;
public TestCaseBeatmapDetails()
{
BeatmapDetails details;
Add(details = new BeatmapDetails
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(150),
Beatmap = new BeatmapInfo
});
AddStep("beatmap all metrics", () => details.Beatmap = new BeatmapInfo
{
Version = "All Metrics",
Metadata = new BeatmapMetadata
{
Version = "VisualTest",
Metadata = new BeatmapMetadata
{
Source = "Some guy",
Tags = "beatmap metadata example with a very very long list of tags and not much creativity",
},
Difficulty = new BeatmapDifficulty
{
CircleSize = 7,
ApproachRate = 3.5f,
OverallDifficulty = 5.7f,
DrainRate = 1,
},
StarDifficulty = 5.3f,
Metrics = new BeatmapMetrics
{
Ratings = Enumerable.Range(0, 10),
Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6),
Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6),
},
Source = "osu!lazer",
Tags = "this beatmap has all the metrics",
},
Difficulty = new BeatmapDifficulty
{
CircleSize = 7,
DrainRate = 1,
OverallDifficulty = 5.7f,
ApproachRate = 3.5f,
},
StarDifficulty = 5.3f,
Metrics = new BeatmapMetrics
{
Ratings = Enumerable.Range(0, 10),
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
},
});
AddRepeatStep("fail values", newRetryAndFailValues, 10);
}
AddStep("beatmap ratings", () => details.Beatmap = new BeatmapInfo
{
Version = "Only Ratings",
Metadata = new BeatmapMetadata
{
Source = "osu!lazer",
Tags = "this beatmap has ratings metrics but not retries or fails",
},
Difficulty = new BeatmapDifficulty
{
CircleSize = 6,
DrainRate = 9,
OverallDifficulty = 6,
ApproachRate = 6,
},
StarDifficulty = 4.8f,
Metrics = new BeatmapMetrics
{
Ratings = Enumerable.Range(0, 10),
},
});
private int lastRange = 1;
AddStep("beatmap fails retries", () => details.Beatmap = new BeatmapInfo
{
Version = "Only Retries and Fails",
Metadata = new BeatmapMetadata
{
Source = "osu!lazer",
Tags = "this beatmap has retries and fails but no ratings",
},
Difficulty = new BeatmapDifficulty
{
CircleSize = 3.7f,
DrainRate = 6,
OverallDifficulty = 6,
ApproachRate = 7,
},
StarDifficulty = 2.91f,
Metrics = new BeatmapMetrics
{
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
},
});
private void newRetryAndFailValues()
{
details.Beatmap.Metrics.Fails = Enumerable.Range(lastRange, 100).Select(i => i % 12 - 6);
details.Beatmap.Metrics.Retries = Enumerable.Range(lastRange - 3, 100).Select(i => i % 12 - 6);
details.Beatmap = details.Beatmap;
lastRange += 100;
AddStep("beatmap no metrics", () => details.Beatmap = new BeatmapInfo
{
Version = "No Metrics",
Metadata = new BeatmapMetadata
{
Source = "osu!lazer",
Tags = "this beatmap has no metrics",
},
Difficulty = new BeatmapDifficulty
{
CircleSize = 5,
DrainRate = 5,
OverallDifficulty = 5.5f,
ApproachRate = 6.5f,
},
StarDifficulty = 1.97f,
Metrics = new BeatmapMetrics(),
});
AddStep("null beatmap", () => details.Beatmap = null);
}
}
}
}

View File

@ -41,12 +41,14 @@ namespace osu.Desktop.Tests.Visual
{
new BeatmapSetInfo
{
OnlineBeatmapSetID = 578332,
Metadata = new BeatmapMetadata
{
Title = @"OrVid",
Artist = @"An",
Author = @"RLC",
Source = @"",
Tags = @"acuticnotes an-fillnote revid tear tearvid encrpted encryption axi axivid quad her hervid recoll",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@ -71,12 +73,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
OnlineBeatmapSetID = 599627,
Metadata = new BeatmapMetadata
{
Title = @"tiny lamp",
Artist = @"fhana",
Author = @"Sotarks",
Source = @"ぎんぎつね",
Tags = @"lantis junichi sato yuxuki waga kevin mitsunaga towana gingitsune opening op full ver version kalibe collab collaboration",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@ -101,12 +105,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
OnlineBeatmapSetID = 513268,
Metadata = new BeatmapMetadata
{
Title = @"At Gwanghwamun",
Artist = @"KYUHYUN",
Author = @"Cerulean Veyron",
Source = @"",
Tags = @"soul ballad kh super junior sj suju 슈퍼주니어 kt뮤직 sm엔터테인먼트 s.m.entertainment kt music 1st mini album ep",
},
OnlineInfo = new BeatmapSetOnlineInfo
{
@ -146,12 +152,14 @@ namespace osu.Desktop.Tests.Visual
},
new BeatmapSetInfo
{
OnlineBeatmapSetID = 586841,
Metadata = new BeatmapMetadata
{
Title = @"RHAPSODY OF BLUE SKY",
Artist = @"fhana",
Author = @"[Kamiya]",
Source = @"小林さんちのメイドラゴン",
Tags = @"kobayashi san chi no maidragon aozora no opening anime maid dragon oblivion karen dynamix imoutosan pata-mon gxytcgxytc",
},
OnlineInfo = new BeatmapSetOnlineInfo
{

View File

@ -0,0 +1,84 @@
// 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.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Edit.Menus;
namespace osu.Desktop.Tests.Visual
{
public class TestCaseEditorMenuBar : OsuTestCase
{
public TestCaseEditorMenuBar()
{
Add(new EditorMenuBar
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Y = 50,
Items = new[]
{
new EditorMenuBarItem("File")
{
Items = new[]
{
new EditorMenuItem("Clear All Notes"),
new EditorMenuItem("Open Difficulty..."),
new EditorMenuItem("Save"),
new EditorMenuItem("Create a new Difficulty..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Revert to Saved"),
new EditorMenuItem("Revert to Saved (Full)"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Test Beatmap"),
new EditorMenuItem("Open AiMod"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Upload Beatmap..."),
new EditorMenuItem("Export Package"),
new EditorMenuItem("Export Map Package"),
new EditorMenuItem("Import from..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Open Song Folder"),
new EditorMenuItem("Open .osu in Notepad"),
new EditorMenuItem("Open .osb in Notepad"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Exit"),
}
},
new EditorMenuBarItem("Timing")
{
Items = new[]
{
new EditorMenuItem("Time Signature"),
new EditorMenuItem("Metronome Clicks"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Add Timing Section"),
new EditorMenuItem("Add Inheriting Section"),
new EditorMenuItem("Reset Current Section"),
new EditorMenuItem("Delete Timing Section"),
new EditorMenuItem("Resnap Current Section"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Timing Setup"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Resnap All Notes", MenuItemType.Destructive),
new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive),
new EditorMenuItem("Recalculate Slider Lengths", MenuItemType.Destructive),
new EditorMenuItem("Delete All Timing Sections", MenuItemType.Destructive),
new EditorMenuItemSpacer(),
new EditorMenuItem("Set Current Position as Preview Point"),
}
},
new EditorMenuBarItem("Testing")
{
Items = new[]
{
new EditorMenuItem("Item 1"),
new EditorMenuItem("Item 2"),
new EditorMenuItem("Item 3"),
}
},
}
});
}
}
}

View File

@ -1,13 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Select.Leaderboards;
using osu.Game.Users;
using OpenTK;
namespace osu.Desktop.Tests.Visual
{
@ -24,7 +24,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.XH,
Accuracy = 100,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -42,7 +42,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.X,
Accuracy = 100,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -60,7 +60,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.SH,
Accuracy = 100,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -78,7 +78,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.S,
Accuracy = 100,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -96,7 +96,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.A,
Accuracy = 100,
Accuracy = 1,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -114,7 +114,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.B,
Accuracy = 98.26,
Accuracy = 0.9826,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -132,7 +132,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.C,
Accuracy = 96.54,
Accuracy = 0.9654,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -150,7 +150,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
Accuracy = 60.25,
Accuracy = 0.6025,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -168,7 +168,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
Accuracy = 51.40,
Accuracy = 0.5140,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },
@ -186,7 +186,7 @@ namespace osu.Desktop.Tests.Visual
new Score
{
Rank = ScoreRank.F,
Accuracy = 42.22,
Accuracy = 0.4222,
MaxCombo = 244,
TotalScore = 1707827,
Mods = new Mod[] { new OsuModHidden(), new OsuModHardRock(), },

View File

@ -41,8 +41,20 @@ namespace osu.Desktop.Tests.Visual
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableNote(new Note { StartTime = 5000 }, ManiaAction.Key1) { AccentColour = Color4.Red },
new DrawableNote(new Note { StartTime = 6000 }, ManiaAction.Key1) { AccentColour = Color4.Red }
new DrawableNote(new Note(), ManiaAction.Key1)
{
Y = 5000,
LifetimeStart = double.MinValue,
LifetimeEnd = double.MaxValue,
AccentColour = Color4.Red
},
new DrawableNote(new Note(), ManiaAction.Key1)
{
Y = 6000,
LifetimeStart = double.MinValue,
LifetimeEnd = double.MaxValue,
AccentColour = Color4.Red
}
}
}
}
@ -63,11 +75,14 @@ namespace osu.Desktop.Tests.Visual
RelativeChildSize = new Vector2(1, 10000),
Children = new[]
{
new DrawableHoldNote(new HoldNote
new DrawableHoldNote(new HoldNote(), ManiaAction.Key1)
{
StartTime = 5000,
Duration = 1000
}, ManiaAction.Key1) { AccentColour = Color4.Red }
Y = 5000,
Height = 1000,
LifetimeStart = double.MinValue,
LifetimeEnd = double.MaxValue,
AccentColour = Color4.Red
}
}
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Desktop.Tests.Visual
backingDatabase.CreateTable<StoreVersion>();
rulesets = new RulesetStore(backingDatabase);
manager = new BeatmapManager(storage, null, backingDatabase, rulesets);
manager = new BeatmapManager(storage, null, backingDatabase, rulesets, null);
for (int i = 0; i < 100; i += 10)
manager.Import(createTestBeatmapSet(i));

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Desktop.Tests</RootNamespace>
<AssemblyName>osu.Desktop.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -87,6 +87,7 @@
<Compile Include="Visual\TestCaseManiaHitObjects.cs" />
<Compile Include="Visual\TestCaseManiaPlayfield.cs" />
<Compile Include="Visual\TestCaseMedalOverlay.cs" />
<Compile Include="Visual\TestCaseEditorMenuBar.cs" />
<Compile Include="Visual\TestCaseMenuButtonSystem.cs" />
<Compile Include="Visual\TestCaseMenuOverlays.cs" />
<Compile Include="Visual\TestCaseMods.cs" />

View File

@ -22,7 +22,7 @@
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
<SignAssembly>false</SignAssembly>
<TargetZone>LocalIntranet</TargetZone>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>

View File

@ -22,7 +22,7 @@
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
<SignAssembly>false</SignAssembly>
<TargetZone>LocalIntranet</TargetZone>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>

View File

@ -93,8 +93,6 @@ namespace osu.Game.Rulesets.Catch
}
}
public override Mod GetAutoplayMod() => new ModAutoplay();
public override string Description => "osu!catch";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };

View File

@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Catch.UI
var additive = createCatcherSprite();
additive.RelativePositionAxes = Axes.Both;
additive.BlendingMode = BlendingMode.Additive;
additive.Blending = BlendingMode.Additive;
additive.Position = Position;
additive.Scale = Scale;

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Rulesets.Catch</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Catch</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Mania
}
}
public override Mod GetAutoplayMod() => new ModAutoplay();
public override string Description => "osu!mania";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };

View File

@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModFadeIn : Mod
{
public override string Name => "FadeIn";
public override string ShortenedName => "FI";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override ModType Type => ModType.DifficultyIncrease;
public override double ScoreMultiplier => 1;
@ -78,12 +79,14 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModRandom : Mod
{
public override string Name => "Random";
public override string ShortenedName => "RD";
public override string Description => @"Shuffle around the notes!";
public override double ScoreMultiplier => 1;
}
public abstract class ManiaKeyMod : Mod
{
public override string ShortenedName => Name;
public abstract int KeyCount { get; }
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
public override bool Ranked => true;
@ -146,6 +149,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModKeyCoop : Mod
{
public override string Name => "KeyCoop";
public override string ShortenedName => "2P";
public override string Description => @"Double the key amount, double the fun!";
public override double ScoreMultiplier => 1;
public override bool Ranked => true;

View File

@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModGravity : Mod, IGenerateSpeedAdjustments
{
public override string Name => "Gravity";
public override string ShortenedName => "GR";
public override double ScoreMultiplier => 0;

View File

@ -1,6 +1,7 @@
// 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.Framework.Extensions.Color4Extensions;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
@ -9,6 +10,7 @@ using OpenTK;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
namespace osu.Game.Rulesets.Mania.Objects.Drawables
@ -23,6 +25,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
private readonly BodyPiece bodyPiece;
private readonly Container<DrawableHoldNoteTick> tickContainer;
private readonly Container glowContainer;
/// <summary>
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
@ -42,13 +45,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddRange(new Drawable[]
{
// For now the body piece covers the entire height of the container
// whereas possibly in the future we don't want to extend under the head/tail.
// This will be fixed when new designs are given or the current design is finalized.
bodyPiece = new BodyPiece
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
},
tickContainer = new Container<DrawableHoldNoteTick>
{
@ -65,6 +66,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
Anchor = Anchor.BottomCentre,
Origin = Anchor.TopCentre
},
// The hit object itself cannot be used for the glow because the tail overshoots it
// So a specialized container that is updated to contain the tail height is used
glowContainer = new Container
{
RelativeSizeAxes = Axes.X,
Masking = true,
Child = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
});
@ -83,6 +97,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
AddNested(tail);
}
protected override void LoadComplete()
{
base.LoadComplete();
updateGlow();
}
public override Color4 AccentColour
{
get { return base.AccentColour; }
@ -97,13 +118,42 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
bodyPiece.AccentColour = value;
head.AccentColour = value;
tail.AccentColour = value;
updateGlow();
}
}
private void updateGlow()
{
if (!IsLoaded)
return;
glowContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = AccentColour.Opacity(0.5f),
Radius = 10,
Hollow = true
};
}
protected override void UpdateState(ArmedState state)
{
}
protected override void Update()
{
base.Update();
// Make the body piece not lie under the head note
bodyPiece.Y = head.Height;
bodyPiece.Height = DrawHeight - head.Height;
// Make the glowContainer "contain" the height of the tail note, keeping in mind
// that the tail note overshoots the height of this hit object
glowContainer.Height = DrawHeight + tail.Height;
}
public bool OnPressed(ManiaAction action)
{
// Make sure the action happened within the body of the hold note
@ -153,6 +203,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativePositionAxes = Axes.None;
Y = 0;
// Life time managed by the parent DrawableHoldNote
LifetimeStart = double.MinValue;
LifetimeEnd = double.MaxValue;
ApplyGlow = false;
}
public override bool OnPressed(ManiaAction action)
@ -190,6 +246,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativePositionAxes = Axes.None;
Y = 0;
// Life time managed by the parent DrawableHoldNote
LifetimeStart = double.MinValue;
LifetimeEnd = double.MaxValue;
ApplyGlow = false;
}
protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement();

View File

@ -23,11 +23,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
/// </summary>
public Func<double?> HoldStartTime;
/// <summary>
/// References whether the user is currently holding the hold note.
/// </summary>
public Func<bool> IsHolding;
private readonly Container glowContainer;
public DrawableHoldNoteTick(HoldNoteTick hitObject)
@ -36,9 +31,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
Y = (float)HitObject.StartTime;
RelativeSizeAxes = Axes.X;
Size = new Vector2(1);
// Life time managed by the parent DrawableHoldNote
LifetimeStart = double.MinValue;
LifetimeEnd = double.MaxValue;
Children = new[]
{
glowContainer = new CircularContainer
@ -112,7 +113,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (Judgement.Result != HitResult.None)
return;
if (IsHolding?.Invoke() != true)
if (HoldStartTime?.Invoke() == null)
return;
UpdateJudgement(true);

View File

@ -1,6 +1,7 @@
// 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.Framework.Graphics;
using OpenTK.Graphics;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
@ -20,6 +21,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null)
: base(hitObject)
{
RelativePositionAxes = Axes.Y;
HitObject = hitObject;
if (action != null)

View File

@ -2,8 +2,10 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Extensions.Color4Extensions;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
@ -16,13 +18,19 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
/// </summary>
public class DrawableNote : DrawableManiaHitObject<Note>, IKeyBindingHandler<ManiaAction>
{
/// <summary>
/// Gets or sets whether this <see cref="DrawableNote"/> should apply glow to itself.
/// </summary>
protected bool ApplyGlow = true;
private readonly NotePiece headPiece;
public DrawableNote(Note hitObject, ManiaAction action)
: base(hitObject, action)
{
RelativeSizeAxes = Axes.X;
Height = 100;
AutoSizeAxes = Axes.Y;
Masking = true;
Add(headPiece = new NotePiece
{
@ -31,6 +39,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
});
}
protected override void LoadComplete()
{
base.LoadComplete();
updateGlow();
}
public override Color4 AccentColour
{
get { return base.AccentColour; }
@ -41,9 +56,28 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
base.AccentColour = value;
headPiece.AccentColour = value;
updateGlow();
}
}
private void updateGlow()
{
if (!IsLoaded)
return;
if (!ApplyGlow)
return;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Colour = AccentColour.Opacity(0.5f),
Radius = 10,
Hollow = true
};
}
protected override void CheckJudgement(bool userTriggered)
{
if (!userTriggered)

View File

@ -1,7 +1,10 @@
// 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;
using osu.Framework.Caching;
using OpenTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
@ -14,22 +17,61 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
/// </summary>
internal class BodyPiece : Container, IHasAccentColour
{
private readonly Box box;
private readonly Container subtractionLayer;
private readonly Drawable background;
private readonly BufferedContainer foreground;
private readonly BufferedContainer subtractionContainer;
public BodyPiece()
{
RelativeSizeAxes = Axes.Both;
Blending = BlendingMode.Additive;
Children = new[]
{
box = new Box
background = new Box { RelativeSizeAxes = Axes.Both },
foreground = new BufferedContainer
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.3f
CacheDrawnFrameBuffer = true,
Children = new Drawable[]
{
new Box { RelativeSizeAxes = Axes.Both },
subtractionContainer = new BufferedContainer
{
RelativeSizeAxes = Axes.Both,
// This is needed because we're blending with another object
BackgroundColour = Color4.White.Opacity(0),
CacheDrawnFrameBuffer = true,
// The 'hole' is achieved by subtracting the result of this container with the parent
Blending = new BlendingParameters { AlphaEquation = BlendingEquation.ReverseSubtract },
Child = subtractionLayer = new CircularContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
// Height computed in Update
Width = 1,
Masking = true,
Child = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
}
}
}
};
}
protected override void LoadComplete()
{
base.LoadComplete();
updateAccentColour();
}
private Color4 accentColour;
public Color4 AccentColour
{
@ -40,8 +82,51 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
return;
accentColour = value;
box.Colour = accentColour;
updateAccentColour();
}
}
private Cached subtractionCache = new Cached();
public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true)
{
if ((invalidation & Invalidation.DrawSize) > 0)
subtractionCache.Invalidate();
return base.Invalidate(invalidation, source, shallPropagate);
}
protected override void Update()
{
base.Update();
if (!subtractionCache.IsValid)
{
subtractionLayer.Width = 5;
subtractionLayer.Height = Math.Max(0, DrawHeight - DrawWidth);
subtractionLayer.EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.White,
Type = EdgeEffectType.Glow,
Radius = DrawWidth
};
foreground.ForceRedraw();
subtractionContainer.ForceRedraw();
subtractionCache.Validate();
}
}
private void updateAccentColour()
{
if (!IsLoaded)
return;
foreground.Colour = AccentColour.Opacity(0.4f);
background.Colour = AccentColour.Opacity(0.2f);
subtractionCache.Invalidate();
}
}
}

View File

@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Mania.UI
{
if (action == Action)
{
background.FadeTo(background.Alpha + 0.2f, 50, Easing.OutQuint);
background.FadeTo(0.6f, 50, Easing.OutQuint);
keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint);
}

View File

@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers;
using System;
using osu.Game.Graphics;
using osu.Framework.Allocation;
using OpenTK.Input;
using System.Linq;
using System.Collections.Generic;
using osu.Framework.Configuration;
@ -25,12 +24,6 @@ namespace osu.Game.Rulesets.Mania.UI
{
public const float HIT_TARGET_POSITION = 50;
/// <summary>
/// Default column keys, expanding outwards from the middle as more column are added.
/// E.g. 2 columns use FJ, 4 columns use DFJK, 6 use SDFJKL, etc...
/// </summary>
private static readonly Key[] default_keys = { Key.A, Key.S, Key.D, Key.F, Key.J, Key.K, Key.L, Key.Semicolon };
private SpecialColumnPosition specialColumnPosition;
/// <summary>
/// The style to use for the special column.

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Rulesets.Mania</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Mania</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@ -96,6 +96,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModSpunOut : Mod
{
public override string Name => "Spun Out";
public override string ShortenedName => "SO";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout;
public override string Description => @"Spinners will be automatically completed";
public override double ScoreMultiplier => 0.9;
@ -106,6 +107,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModAutopilot : Mod
{
public override string Name => "Autopilot";
public override string ShortenedName => "AP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
public override double ScoreMultiplier => 0;
@ -126,6 +128,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModTarget : Mod
{
public override string Name => "Target";
public override string ShortenedName => "TP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_target;
public override string Description => @"";
public override double ScoreMultiplier => 1;

View File

@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
new Box
{
Size = new Vector2(width),
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Alpha = 0.5f,

View File

@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
new TrianglesPiece
{
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Alpha = 0.5f,
}
};

View File

@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
BlendingMode = BlendingMode.Additive;
Blending = BlendingMode.Additive;
Alpha = 0;
Children = new Drawable[]
{
new TrianglesPiece
{
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
RelativeSizeAxes = Axes.Both,
Alpha = 0.2f,
}

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
BlendingMode = BlendingMode.Additive;
Blending = BlendingMode.Additive;
Alpha = 0;
Children = new Drawable[]

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Alpha = 0.5f
}
};

View File

@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.slider = slider;
Masking = true;
AutoSizeAxes = Axes.Both;
BlendingMode = BlendingMode.Additive;
Blending = BlendingMode.Additive;
Origin = Anchor.Centre;
BorderThickness = 10;
BorderColour = Color4.Orange;

View File

@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
path = new Path
{
BlendingMode = BlendingMode.None,
Blending = BlendingMode.None,
},
}
},

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
this.isEnd = isEnd;
AutoSizeAxes = Axes.Both;
BlendingMode = BlendingMode.Additive;
Blending = BlendingMode.Additive;
Origin = Anchor.Centre;
Children = new Drawable[]

View File

@ -51,6 +51,7 @@ namespace osu.Game.Rulesets.Osu.OsuDifficulty.Preprocessing
foreach (OsuDifficultyHitObject h in onScreen)
{
// ReSharper disable once PossibleNullReferenceException (resharper not smart enough to understand IEnumerator.MoveNext())
h.TimeUntilHit -= latest.DeltaTime;
// Calculate reading strain here
}

View File

@ -112,8 +112,6 @@ namespace osu.Game.Rulesets.Osu
}
}
public override Mod GetAutoplayMod() => new OsuModAutoplay();
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap);

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Rulesets.Osu</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Osu</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>

View File

@ -64,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Origin = Anchor.Centre,
Alpha = 0,
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Masking = true,
Children = new[]
{
@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Masking = true,
BorderThickness = target_ring_thick_border,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Children = new Drawable[]
{
new Box

View File

@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Colour = Color4.White,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Alpha = 0,
AlwaysPresent = true
}

View File

@ -95,8 +95,6 @@ namespace osu.Game.Rulesets.Taiko
}
}
public override Mod GetAutoplayMod() => new TaikoModAutoplay();
public override string Description => "osu!taiko";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };

View File

@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.UI
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Alpha = 0,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
},
centre = new Sprite
{
@ -106,7 +106,7 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
Size = new Vector2(0.7f),
Alpha = 0,
BlendingMode = BlendingMode.Additive
Blending = BlendingMode.Additive
}
};
}

View File

@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
},
new HitTarget
{
@ -126,14 +126,14 @@ namespace osu.Game.Rulesets.Taiko.UI
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
BlendingMode = BlendingMode.Additive
Blending = BlendingMode.Additive
},
judgementContainer = new Container<DrawableTaikoJudgement>
{
Name = "Judgements",
RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
BlendingMode = BlendingMode.Additive
Blending = BlendingMode.Additive
},
}
},

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>osu.Game.Rulesets.Taiko</RootNamespace>
<AssemblyName>osu.Game.Rulesets.Taiko</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@ -7,7 +7,7 @@
<OutputType>Library</OutputType>
<RootNamespace>osu.Game.Tests</RootNamespace>
<AssemblyName>osu.Game.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps
public class Beatmap<T>
where T : HitObject
{
public BeatmapInfo BeatmapInfo;
public BeatmapInfo BeatmapInfo = new BeatmapInfo();
public ControlPointInfo ControlPointInfo = new ControlPointInfo();
public List<BreakPeriod> Breaks = new List<BreakPeriod>();
public readonly List<Color4> ComboColors = new List<Color4>
@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps
/// <summary>
/// The HitObjects this Beatmap contains.
/// </summary>
public List<T> HitObjects;
public List<T> HitObjects = new List<T>();
/// <summary>
/// Total amount of break time in the beatmap.
@ -44,12 +44,13 @@ namespace osu.Game.Beatmaps
/// Constructs a new beatmap.
/// </summary>
/// <param name="original">The original beatmap to use the parameters of.</param>
public Beatmap(Beatmap original = null)
public Beatmap(Beatmap<T> original = null)
{
BeatmapInfo = original?.BeatmapInfo.DeepClone() ?? BeatmapInfo;
ControlPointInfo = original?.ControlPointInfo ?? ControlPointInfo;
Breaks = original?.Breaks ?? Breaks;
ComboColors = original?.ComboColors ?? ComboColors;
HitObjects = original?.HitObjects ?? HitObjects;
}
}
@ -65,7 +66,6 @@ namespace osu.Game.Beatmaps
public Beatmap(Beatmap original = null)
: base(original)
{
HitObjects = original?.HitObjects;
}
}
}

View File

@ -20,6 +20,9 @@ using osu.Game.IPC;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
using SQLite.Net;
using osu.Game.Online.API.Requests;
using System.Threading.Tasks;
using osu.Game.Online.API;
namespace osu.Game.Beatmaps
{
@ -63,6 +66,10 @@ namespace osu.Game.Beatmaps
private readonly BeatmapStore beatmaps;
private readonly APIAccess api;
private readonly List<DownloadBeatmapSetRequest> currentDownloads = new List<DownloadBeatmapSetRequest>();
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
private BeatmapIPCChannel ipc;
@ -76,7 +83,7 @@ namespace osu.Game.Beatmaps
/// </summary>
public Func<Storage> GetStableStorage { private get; set; }
public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, IIpcHost importHost = null)
public BeatmapManager(Storage storage, FileStore files, SQLiteConnection connection, RulesetStore rulesets, APIAccess api, IIpcHost importHost = null)
{
beatmaps = new BeatmapStore(connection);
beatmaps.BeatmapSetAdded += s => BeatmapSetAdded?.Invoke(s);
@ -88,6 +95,7 @@ namespace osu.Game.Beatmaps
this.files = files;
this.connection = connection;
this.rulesets = rulesets;
this.api = api;
if (importHost != null)
ipc = new BeatmapIPCChannel(importHost, this);
@ -177,6 +185,74 @@ namespace osu.Game.Beatmaps
beatmaps.Add(beatmapSetInfo);
}
/// <summary>
/// Downloads a beatmap.
/// </summary>
/// <param name="beatmapSetInfo">The <see cref="BeatmapSetInfo"/> to be downloaded.</param>
/// <returns>A new <see cref="DownloadBeatmapSetRequest"/>, or an existing one if a download is already in progress.</returns>
public DownloadBeatmapSetRequest Download(BeatmapSetInfo beatmapSetInfo)
{
var existing = GetExistingDownload(beatmapSetInfo);
if (existing != null) return existing;
if (api == null) return null;
ProgressNotification downloadNotification = new ProgressNotification
{
Text = $"Downloading {beatmapSetInfo.Metadata.Artist} - {beatmapSetInfo.Metadata.Title}",
};
var request = new DownloadBeatmapSetRequest(beatmapSetInfo);
request.DownloadProgressed += progress =>
{
downloadNotification.State = ProgressNotificationState.Active;
downloadNotification.Progress = progress;
};
request.Success += data =>
{
downloadNotification.State = ProgressNotificationState.Completed;
using (var stream = new MemoryStream(data))
using (var archive = new OszArchiveReader(stream))
Import(archive);
currentDownloads.Remove(request);
};
request.Failure += data =>
{
downloadNotification.State = ProgressNotificationState.Completed;
Logger.Error(data, "Failed to get beatmap download information");
currentDownloads.Remove(request);
};
downloadNotification.CancelRequested += () =>
{
request.Cancel();
currentDownloads.Remove(request);
downloadNotification.State = ProgressNotificationState.Cancelled;
return true;
};
currentDownloads.Add(request);
PostNotification?.Invoke(downloadNotification);
// don't run in the main api queue as this is a long-running task.
Task.Run(() => request.Perform(api));
return request;
}
/// <summary>
/// Get an existing download request if it exists.
/// </summary>
/// <param name="beatmap">The <see cref="BeatmapSetInfo"/> whose download request is wanted.</param>
/// <returns>The <see cref="DownloadBeatmapSetRequest"/> object if it exists, or null.</returns>
public DownloadBeatmapSetRequest GetExistingDownload(BeatmapSetInfo beatmap) => currentDownloads.Find(d => d.BeatmapSet.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID);
/// <summary>
/// Delete a beatmap from the manager.
/// Is a no-op for already deleted beatmaps.

View File

@ -7,7 +7,6 @@ using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@ -42,10 +41,7 @@ namespace osu.Game.Beatmaps
this.game = game;
}
protected override Beatmap GetBeatmap() => new Beatmap
{
HitObjects = new List<HitObject>(),
};
protected override Beatmap GetBeatmap() => new Beatmap();
protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4");
@ -59,8 +55,6 @@ namespace osu.Game.Beatmaps
{
public override IEnumerable<Mod> GetModsFor(ModType type) => new Mod[] { };
public override Mod GetAutoplayMod() => new ModAutoplay();
public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset)
{
throw new NotImplementedException();

View File

@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Beatmaps.Formats
{
@ -21,7 +20,7 @@ namespace osu.Game.Beatmaps.Formats
{
string line;
do { line = stream.ReadLine()?.Trim(); }
while (line != null && line.Length == 0);
while (line != null && line.Length == 0);
if (line == null || !decoders.ContainsKey(line))
throw new IOException(@"Unknown file format");
@ -47,7 +46,6 @@ namespace osu.Game.Beatmaps.Formats
{
var beatmap = new Beatmap
{
HitObjects = new List<HitObject>(),
BeatmapInfo = new BeatmapInfo
{
Metadata = new BeatmapMetadata(),

View File

@ -54,7 +54,7 @@ namespace osu.Game.Beatmaps
{
if (beatmap != null) return beatmap;
beatmap = GetBeatmap();
beatmap = GetBeatmap() ?? new Beatmap();
// use the database-backed info.
beatmap.BeatmapInfo = BeatmapInfo;

View File

@ -131,7 +131,7 @@ namespace osu.Game.Graphics.Cursor
},
AdditiveLayer = new Sprite
{
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Colour = colour.Pink,
Alpha = 0,
Texture = textures.Get(@"Cursor/menu-cursor-additive"),

View File

@ -99,7 +99,8 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.ResizeTo(new Vector2(1.5f, 1f), click_duration, Easing.In);
flash();
this.Delay(click_duration).Schedule(delegate {
this.Delay(click_duration).Schedule(delegate
{
colourContainer.ResizeTo(new Vector2(0.8f, 1f));
spriteText.Spacing = Vector2.Zero;
glowContainer.FadeOut();
@ -140,7 +141,7 @@ namespace osu.Game.Graphics.UserInterface
colourContainer.Add(flash);
flash.Colour = ButtonColour;
flash.BlendingMode = BlendingMode.Additive;
flash.Blending = BlendingMode.Additive;
flash.Alpha = 0.3f;
flash.FadeOutFromOne(click_duration);
flash.Expire();

View File

@ -63,7 +63,7 @@ namespace osu.Game.Graphics.UserInterface
hover = new Box
{
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Colour = Color4.White.Opacity(0.1f),
Alpha = 0,
},

View File

@ -96,7 +96,7 @@ namespace osu.Game.Graphics.UserInterface
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuDropdownMenuItem(item) { AccentColour = accentColour };
#region DrawableOsuDropdownMenuItem
protected class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
public class DrawableOsuDropdownMenuItem : DrawableDropdownMenuItem, IHasAccentColour
{
private Color4? accentColour;
public Color4 AccentColour

View File

@ -18,8 +18,8 @@ namespace osu.Game.Graphics.UserInterface
{
public class OsuMenu : Menu
{
public OsuMenu(Direction direction)
: base(direction)
public OsuMenu(Direction direction, bool topLevelMenu = false)
: base(direction, topLevelMenu)
{
BackgroundColour = Color4.Black.Opacity(0.5f);
@ -46,6 +46,11 @@ namespace osu.Game.Graphics.UserInterface
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableOsuMenuItem(item);
protected override Menu CreateSubMenu() => new OsuMenu(Direction.Vertical)
{
Anchor = Direction == Direction.Horizontal ? Anchor.BottomLeft : Anchor.TopRight
};
protected class DrawableOsuMenuItem : DrawableMenuItem
{
private const int margin_horizontal = 17;
@ -61,7 +66,6 @@ namespace osu.Game.Graphics.UserInterface
public DrawableOsuMenuItem(MenuItem item)
: base(item)
{
}
[BackgroundDependencyLoader]
@ -114,9 +118,10 @@ namespace osu.Game.Graphics.UserInterface
return base.OnClick(state);
}
protected override Drawable CreateContent() => text = new TextContainer();
protected sealed override Drawable CreateContent() => text = CreateTextContainer();
protected virtual TextContainer CreateTextContainer() => new TextContainer();
private class TextContainer : Container, IHasText
protected class TextContainer : Container, IHasText
{
public string Text
{

View File

@ -15,11 +15,7 @@ namespace osu.Game.Graphics.UserInterface.Volume
{
private readonly VolumeMeter volumeMeterMaster;
private void volumeChanged(double newVolume)
{
Show();
schedulePopOut();
}
protected override bool BlockPassThroughMouse => false;
public VolumeControl()
{
@ -85,6 +81,12 @@ namespace osu.Game.Graphics.UserInterface.Volume
return false;
}
private void volumeChanged(double newVolume)
{
Show();
schedulePopOut();
}
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{

View File

@ -0,0 +1,24 @@
// 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 System;
namespace osu.Game.Online.API.Requests
{
public class DownloadBeatmapSetRequest : APIDownloadRequest
{
public readonly BeatmapSetInfo BeatmapSet;
public Action<float> DownloadProgressed;
public DownloadBeatmapSetRequest(BeatmapSetInfo set)
{
BeatmapSet = set;
Progress += (current, total) => DownloadProgressed?.Invoke((float) current / total);
}
protected override string Target => $@"beatmapsets/{BeatmapSet.OnlineBeatmapSetID}/download";
}
}

View File

@ -1,10 +1,14 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.IO.Network;
using osu.Game.Beatmaps;
using osu.Game.Users;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Scoring;
namespace osu.Game.Online.API.Requests
@ -16,6 +20,14 @@ namespace osu.Game.Online.API.Requests
public GetScoresRequest(BeatmapInfo beatmap)
{
this.beatmap = beatmap;
Success += onSuccess;
}
private void onSuccess(GetScoresResponse r)
{
foreach (OnlineScore score in r.Scores)
score.ApplyBeatmap(beatmap);
}
protected override WebRequest CreateWebRequest()
@ -32,6 +44,88 @@ namespace osu.Game.Online.API.Requests
public class GetScoresResponse
{
[JsonProperty(@"scores")]
public IEnumerable<Score> Scores;
public IEnumerable<OnlineScore> Scores;
}
}
public class OnlineScore : Score
{
[JsonProperty(@"score")]
private double totalScore
{
set { TotalScore = value; }
}
[JsonProperty(@"max_combo")]
private int maxCombo
{
set { MaxCombo = value; }
}
[JsonProperty(@"user")]
private User user
{
set { User = value; }
}
[JsonProperty(@"replay_data")]
private Replay replay
{
set { Replay = value; }
}
[JsonProperty(@"score_id")]
private long onlineScoreID
{
set { OnlineScoreID = value; }
}
[JsonProperty(@"created_at")]
private DateTimeOffset date
{
set { Date = value; }
}
[JsonProperty(@"statistics")]
private Dictionary<string, dynamic> jsonStats
{
set
{
foreach (var kvp in value)
{
string key = kvp.Key;
switch (key)
{
case @"count_300":
key = @"300";
break;
case @"count_100":
key = @"100";
break;
case @"count_50":
key = @"50";
break;
case @"count_miss":
key = @"x";
break;
default:
continue;
}
Statistics.Add(key, kvp.Value);
}
}
}
[JsonProperty(@"mods")]
private string[] modStrings { get; set; }
public void ApplyBeatmap(BeatmapInfo beatmap)
{
Beatmap = beatmap;
Ruleset = beatmap.Ruleset;
// Evaluate the mod string
Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray();
}
}
}

View File

@ -245,7 +245,11 @@ namespace osu.Game
LoadComponentAsync(Toolbar = new Toolbar
{
Depth = -4,
OnHome = delegate { intro?.ChildScreen?.MakeCurrent(); },
OnHome = delegate
{
hideAllOverlays();
intro?.ChildScreen?.MakeCurrent();
},
}, overlayContent.Add);
settings.StateChanged += delegate
@ -310,6 +314,16 @@ namespace osu.Game
private OsuScreen currentScreen;
private FrameworkConfigManager frameworkConfig;
private void hideAllOverlays()
{
settings.State = Visibility.Hidden;
chat.State = Visibility.Hidden;
direct.State = Visibility.Hidden;
social.State = Visibility.Hidden;
userProfile.State = Visibility.Hidden;
notificationOverlay.State = Visibility.Hidden;
}
private void screenChanged(Screen newScreen)
{
currentScreen = newScreen as OsuScreen;
@ -323,19 +337,12 @@ namespace osu.Game
//central game screen change logic.
if (!currentScreen.ShowOverlays)
{
settings.State = Visibility.Hidden;
Toolbar.State = Visibility.Hidden;
hideAllOverlays();
musicController.State = Visibility.Hidden;
chat.State = Visibility.Hidden;
direct.State = Visibility.Hidden;
social.State = Visibility.Hidden;
userProfile.State = Visibility.Hidden;
notificationOverlay.State = Visibility.Hidden;
Toolbar.State = Visibility.Hidden;
}
else
{
Toolbar.State = Visibility.Visible;
}
ScreenChanged?.Invoke(newScreen);
}

View File

@ -106,9 +106,15 @@ namespace osu.Game
connection.CreateTable<StoreVersion>();
dependencies.Cache(API = new APIAccess
{
Username = LocalConfig.Get<string>(OsuSetting.Username),
Token = LocalConfig.Get<string>(OsuSetting.Token)
});
dependencies.Cache(RulesetStore = new RulesetStore(connection));
dependencies.Cache(FileStore = new FileStore(connection, Host.Storage));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, Host));
dependencies.Cache(BeatmapManager = new BeatmapManager(Host.Storage, FileStore, connection, RulesetStore, API, Host));
dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, connection, Host, BeatmapManager, RulesetStore));
dependencies.Cache(KeyBindingStore = new KeyBindingStore(connection, RulesetStore));
dependencies.Cache(new OsuColour());
@ -144,12 +150,6 @@ namespace osu.Game
Beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
dependencies.Cache(API = new APIAccess
{
Username = LocalConfig.Get<string>(OsuSetting.Username),
Token = LocalConfig.Get<string>(OsuSetting.Token)
});
Beatmap.ValueChanged += b =>
{
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)

View File

@ -76,7 +76,6 @@ namespace osu.Game.Overlays.Chat
Size = new Vector2(text_size),
Shadow = false,
Margin = new MarginPadding { Right = 10f },
Alpha = 0f,
},
},
},
@ -109,7 +108,6 @@ namespace osu.Game.Overlays.Chat
TextSize = text_size,
Font = @"Exo2.0-SemiBold",
Shadow = false,
Alpha = 0.8f,
},
},
},
@ -151,6 +149,9 @@ namespace osu.Game.Overlays.Chat
joinedBind.ValueChanged += updateColour;
joinedBind.BindTo(channel.Joined);
joinedBind.TriggerChange();
FinishTransforms(true);
}
protected override bool OnHover(InputState state)

View File

@ -4,8 +4,6 @@
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using System.IO;
using System.Threading.Tasks;
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -20,8 +18,8 @@ using osu.Framework.Input;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Framework.Logging;
using osu.Game.Beatmaps.IO;
using osu.Game.Overlays.Notifications;
using osu.Game.Online.API.Requests;
namespace osu.Game.Overlays.Direct
{
@ -97,6 +95,11 @@ namespace osu.Game.Overlays.Direct
},
}
});
var downloadRequest = beatmaps.GetExistingDownload(SetInfo);
if (downloadRequest != null)
attachDownload(downloadRequest);
}
protected override bool OnHover(InputState state)
@ -115,23 +118,8 @@ namespace osu.Game.Overlays.Direct
base.OnHoverLost(state);
}
// this should eventually be moved to a more central place, like BeatmapManager.
private DownloadBeatmapSetRequest downloadRequest;
protected void StartDownload()
{
if (api == null) return;
// we already have an active download running.
if (downloadRequest != null)
{
content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine).Then();
return;
}
if (!api.LocalUser.Value.IsSupporter)
{
notifications.Post(new SimpleNotification
@ -142,72 +130,43 @@ namespace osu.Game.Overlays.Direct
return;
}
if (beatmaps.GetExistingDownload(SetInfo) != null)
{
// we already have an active download running.
content.MoveToX(-5, 50, Easing.OutSine).Then()
.MoveToX(5, 100, Easing.InOutSine).Then()
.MoveToX(-5, 100, Easing.InOutSine).Then()
.MoveToX(0, 50, Easing.InSine).Then();
return;
}
var request = beatmaps.Download(SetInfo);
attachDownload(request);
}
private void attachDownload(DownloadBeatmapSetRequest request)
{
progressBar.FadeIn(400, Easing.OutQuint);
progressBar.ResizeHeightTo(4, 400, Easing.OutQuint);
progressBar.Current.Value = 0;
ProgressNotification downloadNotification = new ProgressNotification
{
Text = $"Downloading {SetInfo.Metadata.Artist} - {SetInfo.Metadata.Title}",
};
downloadRequest = new DownloadBeatmapSetRequest(SetInfo);
downloadRequest.Failure += e =>
request.Failure += e =>
{
progressBar.Current.Value = 0;
progressBar.FadeOut(500);
downloadNotification.State = ProgressNotificationState.Completed;
Logger.Error(e, "Failed to get beatmap download information");
downloadRequest = null;
};
downloadRequest.Progress += (current, total) =>
{
float progress = (float)current / total;
request.DownloadProgressed += progress => progressBar.Current.Value = progress;
progressBar.Current.Value = progress;
downloadNotification.State = ProgressNotificationState.Active;
downloadNotification.Progress = progress;
};
downloadRequest.Success += data =>
request.Success += data =>
{
progressBar.Current.Value = 1;
progressBar.FadeOut(500);
downloadNotification.State = ProgressNotificationState.Completed;
using (var stream = new MemoryStream(data))
using (var archive = new OszArchiveReader(stream))
beatmaps.Import(archive);
};
downloadNotification.CancelRequested += () =>
{
downloadRequest.Cancel();
downloadRequest = null;
return true;
};
notifications.Post(downloadNotification);
// don't run in the main api queue as this is a long-running task.
Task.Run(() => downloadRequest.Perform(api));
}
public class DownloadBeatmapSetRequest : APIDownloadRequest
{
private readonly BeatmapSetInfo beatmapSet;
public DownloadBeatmapSetRequest(BeatmapSetInfo beatmapSet)
{
this.beatmapSet = beatmapSet;
}
protected override string Target => $@"beatmapsets/{beatmapSet.OnlineBeatmapSetID}/download";
}
protected override void LoadComplete()

View File

@ -27,6 +27,7 @@ namespace osu.Game.Overlays
private APIAccess api;
private RulesetStore rulesets;
private BeatmapManager beatmaps;
private readonly FillFlowContainer resultCountsContainer;
private readonly OsuSpriteText resultCountsText;
@ -46,9 +47,26 @@ namespace osu.Game.Overlays
set
{
if (beatmapSets?.Equals(value) ?? false) return;
beatmapSets = value;
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
if (beatmapSets == null) return;
var artists = new List<string>();
var songs = new List<string>();
var tags = new List<string>();
foreach (var s in beatmapSets)
{
artists.Add(s.Metadata.Artist);
songs.Add(s.Metadata.Title);
tags.AddRange(s.Metadata.Tags.Split(' '));
}
ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
if (beatmapSets.Any() && panels == null)
// real use case? currently only seems to be for test case
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
}
}
@ -147,6 +165,8 @@ namespace osu.Game.Overlays
{
this.api = api;
this.rulesets = rulesets;
this.beatmaps = beatmaps;
resultCountsContainer.Colour = colours.Yellow;
beatmaps.BeatmapSetAdded += setAdded;
@ -156,6 +176,7 @@ namespace osu.Game.Overlays
{
// if a new map was imported, we should remove it from search results (download completed etc.)
panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire();
BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID);
}
private void updateResultCounts()
@ -237,20 +258,11 @@ namespace osu.Game.Overlays
getSetsRequest.Success += r =>
{
BeatmapSets = r?.Select(response => response.ToBeatmapSet(rulesets));
if (BeatmapSets == null) return;
BeatmapSets = r?.
Select(response => response.ToBeatmapSet(rulesets)).
Where(b => beatmaps.QueryBeatmapSet(q => q.OnlineBeatmapSetID == b.OnlineBeatmapSetID) == null);
var artists = new List<string>();
var songs = new List<string>();
var tags = new List<string>();
foreach (var s in BeatmapSets)
{
artists.Add(s.Metadata.Artist);
songs.Add(s.Metadata.Title);
tags.AddRange(s.Metadata.Tags.Split(' '));
}
ResultAmounts = new ResultCounts(distinctCount(artists), distinctCount(songs), distinctCount(tags));
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
};
api.Queue(getSetsRequest);

View File

@ -302,8 +302,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 = 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();
direction = last > next ? TransformDirection.Prev : TransformDirection.Next;
}

View File

@ -68,7 +68,7 @@ namespace osu.Game.Overlays.Settings
backgroundBox = new Box
{
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Colour = OsuColour.Gray(60),
Alpha = 0,
},

View File

@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(80).Opacity(180),
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Alpha = 0,
},
Flow = new FillFlowContainer

View File

@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Toolbar
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(150).Opacity(180),
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Depth = 2,
Alpha = 0,
});

View File

@ -16,6 +16,11 @@ namespace osu.Game.Rulesets.Mods
/// </summary>
public abstract string Name { get; }
/// <summary>
/// The shortened name of this mod.
/// </summary>
public abstract string ShortenedName { get; }
/// <summary>
/// The icon of this mod.
/// </summary>

View File

@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Mods
public class ModAutoplay : Mod
{
public override string Name => "Autoplay";
public override string ShortenedName => "AT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto;
public override string Description => "Watch a perfect automated play through the song";
public override double ScoreMultiplier => 0;

View File

@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public class ModCinema : ModAutoplay
{
public override string Name => "Cinema";
public override string ShortenedName => "CN";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema;
}
}

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModDaycore : ModHalfTime
{
public override string Name => "Daycore";
public override string ShortenedName => "DC";
public override FontAwesome Icon => FontAwesome.fa_question;
public override string Description => "whoaaaaa";

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public class ModDoubleTime : Mod, IApplicableToClock
{
public override string Name => "Double Time";
public override string ShortenedName => "DT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_doubletime;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Zoooooooooom";

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModEasy : Mod, IApplicableToDifficulty
{
public override string Name => "Easy";
public override string ShortenedName => "EZ";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_easy;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required.";

View File

@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModFlashlight : Mod
{
public override string Name => "Flashlight";
public override string ShortenedName => "FL";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_flashlight;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Restricted view area.";

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHalfTime : Mod, IApplicableToClock
{
public override string Name => "Half Time";
public override string ShortenedName => "HT";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_halftime;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "Less zoom";

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHardRock : Mod, IApplicableToDifficulty
{
public override string Name => "Hard Rock";
public override string ShortenedName => "HR";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hardrock;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Everything just got a bit harder...";

View File

@ -8,6 +8,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModHidden : Mod
{
public override string Name => "Hidden";
public override string ShortenedName => "HD";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override ModType Type => ModType.DifficultyIncrease;
public override bool Ranked => true;

View File

@ -10,6 +10,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModNightcore : ModDoubleTime
{
public override string Name => "Nightcore";
public override string ShortenedName => "NC";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nightcore;
public override string Description => "uguuuuuuuu";

View File

@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModNoFail : Mod
{
public override string Name => "NoFail";
public override string ShortenedName => "NF";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_nofail;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => "You can't fail, no matter what.";

View File

@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModPerfect : ModSuddenDeath
{
public override string Name => "Perfect";
public override string ShortenedName => "PF";
public override string Description => "SS or quit.";
}
}

View File

@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModRelax : Mod
{
public override string Name => "Relax";
public override string ShortenedName => "RX";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_relax;
public override double ScoreMultiplier => 0;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModNoFail), typeof(ModSuddenDeath) };

View File

@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods
public abstract class ModSuddenDeath : Mod
{
public override string Name => "Sudden Death";
public override string ShortenedName => "SD";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_suddendeath;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => "Miss a note and fail.";

View File

@ -6,6 +6,7 @@ namespace osu.Game.Rulesets.Mods
public class MultiMod : Mod
{
public override string Name => string.Empty;
public override string ShortenedName => string.Empty;
public override string Description => string.Empty;
public override double ScoreMultiplier => 0.0;

View File

@ -12,10 +12,11 @@ using osu.Game.Rulesets.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Audio;
using System.Linq;
using osu.Game.Graphics;
namespace osu.Game.Rulesets.Objects.Drawables
{
public abstract class DrawableHitObject : Container
public abstract class DrawableHitObject : Container, IHasAccentColour
{
public readonly HitObject HitObject;

View File

@ -1,15 +1,17 @@
// 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.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Scoring;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets
{
@ -19,9 +21,18 @@ namespace osu.Game.Rulesets
public virtual IEnumerable<BeatmapStatistic> GetBeatmapStatistics(WorkingBeatmap beatmap) => new BeatmapStatistic[] { };
public IEnumerable<Mod> GetAllMods() => Enum.GetValues(typeof(ModType)).Cast<ModType>()
// Get all mod types as an IEnumerable<ModType>
.SelectMany(GetModsFor)
// Confine all mods of each mod type into a single IEnumerable<Mod>
.Where(mod => mod != null)
// Filter out all null mods
.SelectMany(mod => (mod as MultiMod)?.Mods ?? new[] { mod });
// Resolve MultiMods as their .Mods property
public abstract IEnumerable<Mod> GetModsFor(ModType type);
public abstract Mod GetAutoplayMod();
public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay);
protected Ruleset(RulesetInfo rulesetInfo)
{

View File

@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mods;
using osu.Game.Users;
@ -15,70 +14,30 @@ namespace osu.Game.Rulesets.Scoring
{
public ScoreRank Rank { get; set; }
[JsonProperty(@"score")]
public double TotalScore { get; set; }
public double Accuracy { get; set; }
public double Health { get; set; } = 1;
[JsonProperty(@"max_combo")]
public int MaxCombo { get; set; }
public int Combo { get; set; }
[JsonProperty(@"mods")]
protected string[] ModStrings { get; set; } //todo: parse to Mod objects
public RulesetInfo Ruleset { get; set; }
public Mod[] Mods { get; set; }
[JsonProperty(@"user")]
public User User;
[JsonProperty(@"replay_data")]
public Replay Replay;
public BeatmapInfo Beatmap;
[JsonProperty(@"score_id")]
public long OnlineScoreID;
[JsonProperty(@"created_at")]
public DateTimeOffset Date;
[JsonProperty(@"statistics")]
private Dictionary<string, dynamic> jsonStats
{
set
{
foreach (var kvp in value)
{
string key = kvp.Key;
switch (key)
{
case @"count_300":
key = @"300";
break;
case @"count_100":
key = @"100";
break;
case @"count_50":
key = @"50";
break;
case @"count_miss":
key = @"x";
break;
default:
continue;
}
Statistics.Add(key, kvp.Value);
}
}
}
public Dictionary<string, dynamic> Statistics = new Dictionary<string, dynamic>();
}
}

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.UI
private readonly SpriteIcon modIcon;
private readonly SpriteIcon background;
private const float icon_size = 80;
private const float background_size = 80;
public FontAwesome Icon
{
@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.UI
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(icon_size),
Size = new Vector2(background_size),
Icon = FontAwesome.fa_osu_mod_bg,
Shadow = true,
},
@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.UI
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Colour = OsuColour.Gray(84),
Size = new Vector2(icon_size - 35),
Size = new Vector2(background_size - 35),
Y = 25,
Icon = mod.Icon
},

View File

@ -75,9 +75,6 @@ namespace osu.Game.Rulesets.UI
internal RulesetContainer(Ruleset ruleset)
{
Ruleset = ruleset;
KeyBindingInputManager = CreateInputManager();
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
}
/// <summary>
@ -190,6 +187,9 @@ namespace osu.Game.Rulesets.UI
// Post-process the beatmap
processor.PostProcess(Beatmap);
KeyBindingInputManager = CreateInputManager();
KeyBindingInputManager.RelativeSizeAxes = Axes.Both;
// Add mods, should always be the last thing applied to give full control to mods
applyMods(Mods);
}

View File

@ -8,6 +8,11 @@ using osu.Framework.Screens;
using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Select;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Edit.Menus;
namespace osu.Game.Screens.Edit
{
@ -17,6 +22,175 @@ namespace osu.Game.Screens.Edit
protected override BackgroundScreen CreateBackground() => new BackgroundScreenCustom(@"Backgrounds/bg4");
internal override bool ShowOverlays => false;
public Editor()
{
Add(new Container
{
RelativeSizeAxes = Axes.X,
Height = 40,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.FromHex("111")
},
new EditorMenuBar
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
X = 100,
Items = new[]
{
new EditorMenuBarItem("File")
{
Items = new[]
{
new EditorMenuItem("Clear all notes"),
new EditorMenuItem("Open difficulty..."),
new EditorMenuItem("Save"),
new EditorMenuItem("Create new difficulty..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Revert to saved"),
new EditorMenuItem("Revert to saved (full"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Test beatmap"),
new EditorMenuItem("Open AiMod"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Upload Beatmap..."),
new EditorMenuItem("Export package"),
new EditorMenuItem("Export map package"),
new EditorMenuItem("Import from..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Open song folder"),
new EditorMenuItem("Open .osu in Notepad"),
new EditorMenuItem("Open .osb in Notepad"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Exit", MenuItemType.Standard, Exit)
}
},
new EditorMenuBarItem("Edit")
{
Items = new[]
{
new EditorMenuItem("Undo"),
new EditorMenuItem("Redo"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Cut"),
new EditorMenuItem("Copy"),
new EditorMenuItem("Paste"),
new EditorMenuItem("Delete"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Select all"),
new EditorMenuItem("Clone"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Reverse selection"),
new EditorMenuItem("Flip horizontally"),
new EditorMenuItem("Flip vertically"),
new EditorMenuItem("Rotate 90deg clockwise"),
new EditorMenuItem("Rotate 90deg anticlockwise"),
new EditorMenuItem("Rotate by..."),
new EditorMenuItem("Scale by..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Reset selected objects' samples"),
new EditorMenuItem("Reset all samples", MenuItemType.Destructive),
new EditorMenuItem("Reset combo colours", MenuItemType.Destructive),
new EditorMenuItem("Reset breaks", MenuItemType.Destructive),
new EditorMenuItemSpacer(),
new EditorMenuItem("Nudge backward"),
new EditorMenuItem("Nudge forward")
}
},
new EditorMenuBarItem("View")
{
Items = new[]
{
new EditorMenuItem("Compose"),
new EditorMenuItem("Design"),
new EditorMenuItem("Timing"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Song setup..."),
new EditorMenuItem("Timing setup..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Volume"),
new EditorMenuItem("Grid level"),
new EditorMenuItem("Show video"),
new EditorMenuItem("Show sample name"),
new EditorMenuItem("Snaking sliders"),
new EditorMenuItem("Hit animations"),
new EditorMenuItem("Follow points"),
new EditorMenuItem("Stacking")
}
},
new EditorMenuBarItem("Compose")
{
Items = new[]
{
new EditorMenuItem("Snap divisor"),
new EditorMenuItem("Audio rate"),
new EditorMenuItem("Grid snapping"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Create polygon cricles..."),
new EditorMenuItem("Convert slider to stream"),
new EditorMenuItem("Enable live mapping mode"),
new EditorMenuItem("Sample import")
}
},
new EditorMenuBarItem("Design")
{
Items = new[]
{
new EditorMenuItem("Move all elements in time...")
}
},
new EditorMenuBarItem("Timing")
{
Items = new[]
{
new EditorMenuItem("Time signature"),
new EditorMenuItem("Metronome clicks"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Add timing section"),
new EditorMenuItem("Add inheriting section"),
new EditorMenuItem("Reset current section"),
new EditorMenuItem("Delete timing section"),
new EditorMenuItem("Resnap current section"),
new EditorMenuItemSpacer(),
new EditorMenuItem("Timing setup..."),
new EditorMenuItemSpacer(),
new EditorMenuItem("Resnap all notes", MenuItemType.Destructive),
new EditorMenuItem("Move all notes in time...", MenuItemType.Destructive),
new EditorMenuItem("Recalculate slider lengths", MenuItemType.Destructive),
new EditorMenuItem("Delete all timing sections", MenuItemType.Destructive),
new EditorMenuItemSpacer(),
new EditorMenuItem("Set current position as preview point")
}
},
new EditorMenuBarItem("Web")
{
Items = new[]
{
new EditorMenuItem("This Beatmap's information page"),
new EditorMenuItem("This Beatmap's thread"),
new EditorMenuItem("Quick reply")
}
},
new EditorMenuBarItem("Help")
{
Items = new[]
{
new EditorMenuItem("Show in-game help"),
new EditorMenuItem("View FAQ")
}
}
}
}
}
});
}
protected override void OnResuming(Screen last)
{
Beatmap.Value.Track?.Stop();

View File

@ -0,0 +1,122 @@
// 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.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using OpenTK;
using OpenTK.Graphics;
namespace osu.Game.Screens.Edit.Menus
{
public class EditorMenuBar : OsuMenu
{
public EditorMenuBar()
: base(Direction.Horizontal, true)
{
ItemsContainer.Padding = new MarginPadding(0);
BackgroundColour = Color4.Transparent;
}
protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableEditorBarMenuItem(item);
private class DrawableEditorBarMenuItem : DrawableOsuMenuItem
{
private Color4 openedForegroundColour;
private Color4 openedBackgroundColour;
public DrawableEditorBarMenuItem(MenuItem item)
: base(item)
{
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
ForegroundColour = ForegroundColourHover = colours.BlueLight;
BackgroundColour = BackgroundColourHover = Color4.Transparent;
openedForegroundColour = Color4.White;
openedBackgroundColour = colours.Gray3;
}
protected override void UpdateBackgroundColour()
{
if (State == MenuItemState.Selected)
Background.FadeColour(openedBackgroundColour);
else
base.UpdateBackgroundColour();
}
protected override void UpdateForegroundColour()
{
if (State == MenuItemState.Selected)
Foreground.FadeColour(openedForegroundColour);
else
base.UpdateForegroundColour();
}
protected override Drawable CreateBackground() => new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
Child = new Container
{
RelativeSizeAxes = Axes.Both,
Height = 2,
Masking = true,
CornerRadius = 4,
Child = new Box { RelativeSizeAxes = Axes.Both }
}
};
}
private class SubMenu : OsuMenu
{
public SubMenu()
: base(Direction.Vertical)
{
OriginPosition = new Vector2(5, 1);
ItemsContainer.Padding = new MarginPadding { Top = 5, Bottom = 5 };
}
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
BackgroundColour = colours.Gray3;
}
protected override Framework.Graphics.UserInterface.Menu CreateSubMenu() => new SubMenu();
protected override DrawableMenuItem CreateDrawableMenuItem(MenuItem item) => new DrawableSubMenuItem(item);
private class DrawableSubMenuItem : DrawableOsuMenuItem
{
public DrawableSubMenuItem(MenuItem item)
: base(item)
{
}
protected override bool OnHover(InputState state)
{
if (Item is EditorMenuItemSpacer)
return true;
return base.OnHover(state);
}
protected override bool OnClick(InputState state)
{
if (Item is EditorMenuItemSpacer)
return true;
return base.OnClick(state);
}
}
}
}
}

View File

@ -0,0 +1,15 @@
// 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.Framework.Graphics.UserInterface;
namespace osu.Game.Screens.Edit.Menus
{
public class EditorMenuBarItem : MenuItem
{
public EditorMenuBarItem(string text)
: base(text)
{
}
}
}

View File

@ -0,0 +1,23 @@
// 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;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Screens.Edit.Menus
{
public class EditorMenuItem : OsuMenuItem
{
private const int min_text_length = 40;
public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard)
: base(text.PadRight(min_text_length), type)
{
}
public EditorMenuItem(string text, MenuItemType type, Action action)
: base(text.PadRight(min_text_length), type, action)
{
}
}
}

View File

@ -0,0 +1,13 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Edit.Menus
{
public class EditorMenuItemSpacer : EditorMenuItem
{
public EditorMenuItemSpacer()
: base(" ")
{
}
}
}

View File

@ -83,7 +83,7 @@ namespace osu.Game.Screens.Menu
{
EdgeSmoothness = new Vector2(1.5f, 0),
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Colour = Color4.White,
Alpha = 0,
},

View File

@ -52,7 +52,7 @@ namespace osu.Game.Screens.Menu
{
Alpha = 0,
Triangles = false,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Interactive = false,
Colour = Color4.DarkGray,
Ripple = false

View File

@ -73,7 +73,7 @@ namespace osu.Game.Screens.Menu
{
texture = Texture.WhitePixel;
AccentColour = new Color4(1, 1, 1, 0.2f);
BlendingMode = BlendingMode.Additive;
Blending = BlendingMode.Additive;
}
[BackgroundDependencyLoader]

View File

@ -50,7 +50,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
},
rightBox = new Box
{
@ -59,7 +59,7 @@ namespace osu.Game.Screens.Menu
RelativeSizeAxes = Axes.Y,
Width = box_width,
Alpha = 0,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
}
};
}

View File

@ -108,7 +108,7 @@ namespace osu.Game.Screens.Menu
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Alpha = 0
}
}
@ -169,7 +169,7 @@ namespace osu.Game.Screens.Menu
flashLayer = new Box
{
RelativeSizeAxes = Axes.Both,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
Colour = Color4.White,
Alpha = 0,
},

View File

@ -28,6 +28,8 @@ namespace osu.Game.Screens.Play
public override void Add(KeyCounter key)
{
if (key == null) throw new ArgumentNullException(nameof(key));
base.Add(key);
key.IsCounting = IsCounting;
key.FadeTime = FadeTime;

View File

@ -100,7 +100,7 @@ namespace osu.Game.Screens
Colour = getColourFor(GetType()),
Alpha = 0.2f,
BlendingMode = BlendingMode.Additive,
Blending = BlendingMode.Additive,
},
textContainer = new FillFlowContainer
{

Some files were not shown because too many files have changed in this diff Show More