1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 03:25:11 +08:00

Merge remote-tracking branch 'upstream/master' into facade-container

This commit is contained in:
David Zhao 2019-04-02 11:28:44 +09:00
commit 020be50f03
267 changed files with 1996 additions and 2130 deletions

View File

@ -1,11 +0,0 @@
osu!lazer is currently still under heavy development!
Please ensure that you are making an issue for one of the following:
- A bug with currently implemented features (not features that don't exist)
- A feature you are considering adding, so we can collaborate on feedback and design.
- Discussions about technical design decisions
If your issue qualifies, replace this text with a detailed description of your issue with as much relevant information as you can provide.
Screenshots and log files are highly welcomed.

View File

@ -1,14 +1,11 @@
---
name: Bug Report
about: For issues regarding encountered game bugs
about: Issues regarding encountered bugs.
---
<!-- After you fill in all information, delete all comments in the issue -->
**Describe your problem:** <!-- Provide any information you believe could be useful -->
**Describe the bug:**
**Screenshots or videos showing encountered issue:**
**osu!lazer version:** <!-- Provide the version of your osu!lazer, you can find it at the bottom of the screen -->
**osu!lazer version:**
**Logs:** <!-- Attach your osu!lazer logs, you can find them under %appdata%\osu\logs in Windows, or under ~/.local/share/osu/ in Linux and macOS -->
**Logs:**

View File

@ -1,16 +1,13 @@
---
name: Crash Report
about: For issues regarding game crashes or permanent freezes
about: Issues regarding crashes or permanent freezes.
---
<!-- After you fill in all information, delete all comments in the issue -->
**Describe your problem:** <!-- Provide any information you believe could be useful -->
**Describe the crash:**
**Screenshots or videos showing encountered issue:**
**osu!lazer version:** <!-- Provide the version of your osu!lazer, you can find it at the bottom of the screen -->
**osu!lazer version:**
**Logs:** <!-- Attach your osu!lazer logs, you can find them under %appdata%\osu\logs in Windows, or under ~/.local/share/osu/ in Linux and macOS -->
**Logs:**
**Computer Specifications:** <!-- Attach your computer specifications, you can find them by using System Information in Windows, System Monitor in Linux, or About This Mac in macOS -->
**Computer Specifications:**

View File

@ -1,10 +1,7 @@
---
name: Feature Request
about: Let us know what you would like to see in the game!
about: Features you would like to see in the game!
---
**Describe the new feature:**
<!-- After you fill in all information, delete all comments in the issue -->
**Describe the feature:** <!-- Describe the feature you would like to see in the game -->
**Proposal designs of the feature:** <!-- Attach screenshots of how the feature should look like according to you -->
**Proposal designs of the feature:**

View File

@ -1,10 +1,7 @@
---
name: Missing for Live
about: Let us know the features you need which are available in osu-stable but not lazer
about: Features which are available in osu!stable but not yet in osu!lazer.
---
**Describe the missing feature:**
<!-- After you fill in all information, delete all comments in the issue -->
**Describe the feature:** <!-- Describe the missing game feature -->
**Designs:** <!-- Attach screenshots of how the feature is supposed to look like. For illustrative purpose only; final designs are usually re-imagined from scratch. -->
**Proposal designs of the feature:**

View File

@ -14,6 +14,7 @@ using osuTK.Input;
using Microsoft.Win32;
using osu.Desktop.Updater;
using osu.Framework;
using osu.Framework.Logging;
using osu.Framework.Platform.Windows;
using osu.Framework.Screens;
using osu.Game.Screens.Menu;
@ -35,12 +36,15 @@ namespace osu.Desktop
{
try
{
return new StableStorage();
if (Host is DesktopGameHost desktopHost)
return new StableStorage(desktopHost);
}
catch
catch (Exception e)
{
return null;
Logger.Error(e, "Error while searching for stable install");
}
return null;
}
protected override void LoadComplete()
@ -139,8 +143,8 @@ namespace osu.Desktop
return null;
}
public StableStorage()
: base(string.Empty, null)
public StableStorage(DesktopGameHost host)
: base(string.Empty, host)
{
}
}

View File

@ -110,7 +110,7 @@ namespace osu.Desktop.Overlays
public UpdateCompleteNotification(string version, Action<string> openUrl = null)
{
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
Icon = FontAwesome.fa_check_square;
Icon = FontAwesome.CheckSquare;
Activated = delegate
{
openUrl?.Invoke($"https://osu.ppy.sh/home/changelog/lazer/{version}");

View File

@ -7,10 +7,10 @@ using Newtonsoft.Json;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.IO.Network;
using osu.Framework.Platform;
using osu.Game;
using osu.Game.Graphics;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
@ -54,7 +54,7 @@ namespace osu.Desktop.Updater
{
Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n"
+ "Click here to download the new version, which can be installed over the top of your existing installation",
Icon = FontAwesome.fa_upload,
Icon = FontAwesome.Upload,
Activated = () =>
{
host.OpenUrlExternally(getBestUrl(latest));

View File

@ -9,6 +9,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Logging;
using osu.Game;
using osu.Game.Graphics;
@ -158,7 +159,7 @@ namespace osu.Desktop.Updater
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Icon = FontAwesome.fa_upload,
Icon = FontAwesome.Upload,
Colour = Color4.White,
Size = new Vector2(20),
}

View File

@ -3,8 +3,8 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects;
namespace osu.Game.Rulesets.Catch.Beatmaps
@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
{
Name = @"Fruit Count",
Content = fruits.ToString(),
Icon = FontAwesome.fa_circle_o
Icon = FontAwesome.CircleOutline
},
new BeatmapStatistic
{
Name = @"Juice Stream Count",
Content = juiceStreams.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
},
new BeatmapStatistic
{
Name = @"Banana Shower Count",
Content = bananaShowers.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
}
};
}

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Replays;
@ -17,6 +18,7 @@ using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Scoring;
namespace osu.Game.Rulesets.Catch
{
@ -114,10 +116,12 @@ namespace osu.Game.Rulesets.Catch
public override string ShortName => "fruits";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score);
public override int? LegacyID => 2;
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();

View File

@ -0,0 +1,104 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Scoring.Legacy;
using osuTK;
namespace osu.Game.Rulesets.Catch.Difficulty
{
public class CatchPerformanceCalculator : PerformanceCalculator
{
protected new CatchDifficultyAttributes Attributes => (CatchDifficultyAttributes)base.Attributes;
private Mod[] mods;
private int fruitsHit;
private int ticksHit;
private int tinyTicksHit;
private int tinyTicksMissed;
private int misses;
public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score)
: base(ruleset, beatmap, score)
{
}
public override double Calculate(Dictionary<string, double> categoryDifficulty = null)
{
mods = Score.Mods;
var legacyScore = Score as LegacyScoreInfo;
fruitsHit = legacyScore?.Count300 ?? Score.Statistics[HitResult.Perfect];
ticksHit = legacyScore?.Count100 ?? 0;
tinyTicksHit = legacyScore?.Count50 ?? 0;
tinyTicksMissed = legacyScore?.CountKatu ?? 0;
misses = Score.Statistics[HitResult.Miss];
// Don't count scores made with supposedly unranked mods
if (mods.Any(m => !m.Ranked))
return 0;
// We are heavily relying on aim in catch the beat
double value = Math.Pow(5.0f * Math.Max(1.0f, Attributes.StarRating / 0.0049f) - 4.0f, 2.0f) / 100000.0f;
// Longer maps are worth more. "Longer" means how many hits there are which can contribute to combo
int numTotalHits = totalComboHits();
// Longer maps are worth more
float lengthBonus =
0.95f + 0.4f * Math.Min(1.0f, numTotalHits / 3000.0f) +
(numTotalHits > 3000 ? (float)Math.Log10(numTotalHits / 3000.0f) * 0.5f : 0.0f);
// Longer maps are worth more
value *= lengthBonus;
// Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available
value *= Math.Pow(0.97f, misses);
// Combo scaling
float beatmapMaxCombo = Attributes.MaxCombo;
if (beatmapMaxCombo > 0)
value *= Math.Min(Math.Pow(Attributes.MaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
float approachRate = (float)Attributes.ApproachRate;
float approachRateFactor = 1.0f;
if (approachRate > 9.0f)
approachRateFactor += 0.1f * (approachRate - 9.0f); // 10% for each AR above 9
else if (approachRate < 8.0f)
approachRateFactor += 0.025f * (8.0f - approachRate); // 2.5% for each AR below 8
value *= approachRateFactor;
if (mods.Any(m => m is ModHidden))
// Hiddens gives nothing on max approach rate, and more the lower it is
value *= 1.05f + 0.075f * (10.0f - Math.Min(10.0f, approachRate)); // 7.5% for each AR below 10
if (mods.Any(m => m is ModFlashlight))
// Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps.
value *= 1.35f * lengthBonus;
// Scale the aim value with accuracy _slightly_
value *= Math.Pow(accuracy(), 5.5f);
// Custom multipliers for NoFail. SpunOut is not applicable.
if (mods.Any(m => m is ModNoFail))
value *= 0.90f;
return value;
}
private float accuracy() => totalHits() == 0 ? 0 : MathHelper.Clamp((float)totalSuccessfulHits() / totalHits(), 0f, 1f);
private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
private int totalComboHits() => misses + ticksHit + fruitsHit;
}
}

View File

@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
private readonly Container bananaContainer;
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
: base(s)
{
RelativeSizeAxes = Axes.X;
Origin = Anchor.BottomLeft;
X = 0;
InternalChild = bananaContainer = new Container { RelativeSizeAxes = Axes.Both };
AddInternal(bananaContainer = new Container { RelativeSizeAxes = Axes.Both });
foreach (var b in s.NestedHitObjects.Cast<Banana>())
AddNested(getVisualRepresentation?.Invoke(b));
AddNested(createDrawableRepresentation?.Invoke(b));
}
protected override void AddNested(DrawableHitObject h)

View File

@ -26,10 +26,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
[BackgroundDependencyLoader]
private void load()
{
InternalChild = pulp = new Pulp
{
Size = Size
};
AddInternal(pulp = new Pulp { Size = Size });
}
public override Color4 AccentColour

View File

@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
// todo: this should come from the skin.
AccentColour = colourForRepresentation(HitObject.VisualRepresentation);
InternalChildren = new[]
AddRangeInternal(new[]
{
createPulp(HitObject.VisualRepresentation),
border = new Circle
@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
}
}
},
};
});
if (HitObject.HyperDash)
{

View File

@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
private readonly Container dropletContainer;
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation = null)
: base(s)
{
RelativeSizeAxes = Axes.Both;
Origin = Anchor.BottomLeft;
X = 0;
InternalChild = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, };
AddInternal(dropletContainer = new Container { RelativeSizeAxes = Axes.Both, });
foreach (var o in s.NestedHitObjects.Cast<CatchHitObject>())
AddNested(getVisualRepresentation?.Invoke(o));
AddNested(createDrawableRepresentation?.Invoke(o));
}
protected override void AddNested(DrawableHitObject h)

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Diagnostics;
using osu.Framework.Input.StateChanges;
using osu.Framework.MathUtils;
using osu.Game.Replays;
@ -22,10 +23,14 @@ namespace osu.Game.Rulesets.Catch.Replays
{
get
{
if (!HasFrames)
var frame = CurrentFrame;
if (frame == null)
return null;
return Interpolation.ValueAt(CurrentTime, CurrentFrame.Position, NextFrame.Position, CurrentFrame.Time, NextFrame.Time);
Debug.Assert(CurrentTime != null);
return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position;
}
}

View File

@ -10,7 +10,6 @@ using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
namespace osu.Game.Rulesets.Catch.UI
{
@ -20,33 +19,24 @@ namespace osu.Game.Rulesets.Catch.UI
internal readonly CatcherArea CatcherArea;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> createDrawableRepresentation)
{
Container explodingFruitContainer;
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate
InternalChild = new PlayfieldAdjustmentContainer
InternalChildren = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
explodingFruitContainer = new Container
{
explodingFruitContainer = new Container
{
RelativeSizeAxes = Axes.Both,
},
CatcherArea = new CatcherArea(difficulty)
{
GetVisualRepresentation = getVisualRepresentation,
ExplodingFruitTarget = explodingFruitContainer,
Anchor = Anchor.BottomLeft,
Origin = Anchor.TopLeft,
},
HitObjectContainer
}
RelativeSizeAxes = Axes.Both,
},
CatcherArea = new CatcherArea(difficulty)
{
CreateDrawableRepresentation = createDrawableRepresentation,
ExplodingFruitTarget = explodingFruitContainer,
Anchor = Anchor.BottomLeft,
Origin = Anchor.TopLeft,
},
HitObjectContainer
};
}

View File

@ -3,17 +3,23 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.UI;
using osuTK;
namespace osu.Game.Rulesets.Catch.UI
{
public class PlayfieldAdjustmentContainer : Container
public class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
protected override Container<Drawable> Content => content;
private readonly Container content;
public PlayfieldAdjustmentContainer()
public CatchPlayfieldAdjustmentContainer()
{
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate
InternalChild = new Container
{
Anchor = Anchor.Centre,

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.UI
protected internal readonly Catcher MovableCatcher;
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> GetVisualRepresentation;
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> CreateDrawableRepresentation;
public Container ExplodingFruitTarget
{
@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Catch.UI
if (result.IsHit && fruit.CanBePlated)
{
var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject);
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);
if (caughtFruit == null) return;

View File

@ -34,11 +34,13 @@ namespace osu.Game.Rulesets.Catch.UI
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation);
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new CatchPlayfieldAdjustmentContainer();
protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
public override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
public override DrawableHitObject<CatchHitObject> CreateDrawableRepresentation(CatchHitObject h)
{
switch (h)
{
@ -47,9 +49,9 @@ namespace osu.Game.Rulesets.Catch.UI
case Fruit fruit:
return new DrawableFruit(fruit);
case JuiceStream stream:
return new DrawableJuiceStream(stream, GetVisualRepresentation);
return new DrawableJuiceStream(stream, CreateDrawableRepresentation);
case BananaShower shower:
return new DrawableBananaShower(shower, GetVisualRepresentation);
return new DrawableBananaShower(shower, CreateDrawableRepresentation);
case TinyDroplet tiny:
return new DrawableTinyDroplet(tiny);
case Droplet droplet:

View File

@ -3,8 +3,8 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
@ -42,13 +42,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{
Name = @"Note Count",
Content = notes.ToString(),
Icon = FontAwesome.fa_circle_o
Icon = FontAwesome.CircleOutline
},
new BeatmapStatistic
{
Name = @"Hold Note Count",
Content = holdnotes.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
},
};
}

View File

@ -10,6 +10,7 @@ using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
@ -160,7 +161,7 @@ namespace osu.Game.Rulesets.Mania
public override string ShortName => "mania";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap);

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override string Name => "Fade In";
public override string Acronym => "FI";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
public override IconUsage Icon => OsuIcon.ModHidden;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => @"Keys appear out of nowhere!";
public override double ScoreMultiplier => 1;

View File

@ -3,6 +3,7 @@
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
@ -17,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Random";
public override string Acronym => "RD";
public override ModType Type => ModType.Conversion;
public override FontAwesome Icon => FontAwesome.fa_osu_dice;
public override IconUsage Icon => OsuIcon.Dice;
public override string Description => @"Shuffle around the keys!";
public override double ScoreMultiplier => 1;

View File

@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
RelativeSizeAxes = Axes.X;
InternalChildren = new Drawable[]
AddRangeInternal(new Drawable[]
{
bodyPiece = new BodyPiece
{
@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
}
};
});
foreach (var tick in tickContainer)
AddNested(tick);

View File

@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
RelativeSizeAxes = Axes.X;
Size = new Vector2(1);
InternalChildren = new[]
AddRangeInternal(new[]
{
glowContainer = new CircularContainer
{
@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
}
}
}
};
});
}
public override Color4 AccentColour

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
CornerRadius = 5;
Masking = true;
InternalChild = headPiece = new NotePiece();
AddInternal(headPiece = new NotePiece());
}
protected override void OnDirectionChanged(ValueChangedEvent<ScrollingDirection> e)

View File

@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Mania.Replays
protected override bool IsImportant(ManiaReplayFrame frame) => frame.Actions.Any();
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<ManiaAction> { PressedActions = CurrentFrame.Actions } };
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<ManiaAction> { PressedActions = CurrentFrame?.Actions ?? new List<ManiaAction>() } };
}
}

View File

@ -6,7 +6,6 @@ using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
@ -89,11 +88,9 @@ namespace osu.Game.Rulesets.Mania.UI
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
public Column GetColumnByPosition(Vector2 screenSpacePosition) => Playfield.GetColumnByPosition(screenSpacePosition);
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
};
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new ManiaPlayfieldAdjustmentContainer();
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
@ -101,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
public override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
public override DrawableHitObject<ManiaHitObject> CreateDrawableRepresentation(ManiaHitObject h)
{
switch (h)
{

View File

@ -28,8 +28,6 @@ namespace osu.Game.Rulesets.Mania.UI
if (stageDefinitions.Count <= 0)
throw new ArgumentException("Can't have zero or fewer stages.");
Size = new Vector2(1, 0.8f);
GridContainer playfieldGrid;
AddInternal(playfieldGrid = new GridContainer
{

View File

@ -0,0 +1,20 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Game.Rulesets.UI;
using osuTK;
namespace osu.Game.Rulesets.Mania.UI
{
public class ManiaPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
public ManiaPlayfieldAdjustmentContainer()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Size = new Vector2(1, 0.8f);
}
}
}

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets.Osu.UI.Cursor;
using osu.Game.Rulesets.UI;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
@ -27,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Tests
[BackgroundDependencyLoader]
private void load()
{
Add(cursorContainer = new GameplayCursorContainer { RelativeSizeAxes = Axes.Both });
Add(cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both });
}
}
}

View File

@ -297,11 +297,6 @@ namespace osu.Game.Rulesets.Osu.Tests
private void performTest(List<ReplayFrame> frames)
{
// Empty frame to be added as a workaround for first frame behavior.
// If an input exists on the first frame, the input would apply to the entire intro lead-in
// Likely requires some discussion regarding how first frame inputs should be handled.
frames.Insert(0, new OsuReplayFrame());
AddStep("load player", () =>
{
Beatmap.Value = new TestWorkingBeatmap(new Beatmap<OsuHitObject>
@ -330,12 +325,7 @@ namespace osu.Game.Rulesets.Osu.Tests
},
}, Clock);
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } })
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false
};
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
p.OnLoadComplete += _ =>
{
@ -364,7 +354,7 @@ namespace osu.Game.Rulesets.Osu.Tests
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
public ScoreAccessibleReplayPlayer(Score score)
: base(score)
: base(score, false, false)
{
}
}

View File

@ -3,8 +3,8 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Osu.Objects;
namespace osu.Game.Rulesets.Osu.Beatmaps
@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
{
Name = @"Circle Count",
Content = circles.ToString(),
Icon = FontAwesome.fa_circle_o
Icon = FontAwesome.CircleOutline
},
new BeatmapStatistic
{
Name = @"Slider Count",
Content = sliders.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
},
new BeatmapStatistic
{
Name = @"Spinner Count",
Content = spinners.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
}
};
}

View File

@ -1,7 +1,6 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Cursor;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
@ -16,11 +15,13 @@ namespace osu.Game.Rulesets.Osu.Edit
{
}
protected override Playfield CreatePlayfield() => new OsuPlayfieldNoCursor { Size = Vector2.One };
protected override Playfield CreatePlayfield() => new OsuPlayfieldNoCursor();
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer { Size = Vector2.One };
private class OsuPlayfieldNoCursor : OsuPlayfield
{
protected override CursorContainer CreateCursor() => null;
protected override GameplayCursorContainer CreateCursor() => null;
}
}
}

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
@ -13,7 +11,6 @@ using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Edit.Compose.Components;
@ -38,8 +35,6 @@ namespace osu.Game.Rulesets.Osu.Edit
public override SelectionHandler CreateSelectionHandler() => new OsuSelectionHandler();
protected override Container CreateLayerContainer() => new PlayfieldAdjustmentContainer { RelativeSizeAxes = Axes.Both };
public override SelectionBlueprint CreateBlueprintFor(DrawableHitObject hitObject)
{
switch (hitObject)

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
@ -11,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override string Name => "Autopilot";
public override string Acronym => "AP";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot;
public override IconUsage Icon => OsuIcon.ModAutopilot;
public override ModType Type => ModType.Automation;
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
public override double ScoreMultiplier => 1;

View File

@ -8,7 +8,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Scoring;
@ -24,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override string Description => "Play with blinds on your screen.";
public override string Acronym => "BL";
public override FontAwesome Icon => FontAwesome.fa_adjust;
public override IconUsage Icon => FontAwesome.Adjust;
public override ModType Type => ModType.DifficultyIncrease;
public override bool Ranked => false;

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override string Acronym => "GR";
public override FontAwesome Icon => FontAwesome.fa_arrows_v;
public override IconUsage Icon => FontAwesome.ArrowsV;
public override ModType Type => ModType.Fun;

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
@ -11,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override string Name => "Spun Out";
public override string Acronym => "SO";
public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout;
public override IconUsage Icon => OsuIcon.ModSpunout;
public override ModType Type => ModType.DifficultyReduction;
public override string Description => @"Spinners will be automatically completed.";
public override double ScoreMultiplier => 0.9;

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mods;
@ -11,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override string Name => "Target";
public override string Acronym => "TP";
public override ModType Type => ModType.Conversion;
public override FontAwesome Icon => FontAwesome.fa_osu_mod_target;
public override IconUsage Icon => OsuIcon.ModTarget;
public override string Description => @"Practice keeping up with the beat of the song.";
public override double ScoreMultiplier => 1;
}

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override string Name => "Transform";
public override string Acronym => "TR";
public override FontAwesome Icon => FontAwesome.fa_arrows;
public override IconUsage Icon => FontAwesome.Arrows;
public override ModType Type => ModType.Fun;
public override string Description => "Everything rotates. EVERYTHING.";
public override double ScoreMultiplier => 1;

View File

@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
public override string Name => "Wiggle";
public override string Acronym => "WG";
public override FontAwesome Icon => FontAwesome.fa_certificate;
public override IconUsage Icon => FontAwesome.Certificate;
public override ModType Type => ModType.Fun;
public override string Description => "They just won't stay still...";
public override double ScoreMultiplier => 1;

View File

@ -4,10 +4,10 @@
using System;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
using osu.Game.Graphics;
using osu.Game.Rulesets.Scoring;
using osu.Game.Skinning;
@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
new SkinnableDrawable("Play/osu/reversearrow", _ => new SpriteIcon
{
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.fa_chevron_right
Icon = FontAwesome.ChevronRight
}, restrictSize: false)
};
}

View File

@ -12,6 +12,7 @@ using osu.Game.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Game.Screens.Ranking;
using osu.Game.Rulesets.Scoring;
@ -76,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(48),
Icon = FontAwesome.fa_asterisk,
Icon = FontAwesome.Asterisk,
Shadow = false,
},
}

View File

@ -6,6 +6,7 @@ using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Objects.Types;
using osuTK.Graphics;
@ -14,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public class SliderBall : CircularContainer, ISliderProgress
public class SliderBall : CircularContainer, ISliderProgress, IRequireHighFrequencyMousePosition
{
private const float width = 128;
@ -107,18 +108,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
private Vector2? lastScreenSpaceMousePosition;
protected override bool OnMouseDown(MouseDownEvent e)
{
lastScreenSpaceMousePosition = e.ScreenSpaceMousePosition;
return base.OnMouseDown(e);
}
protected override bool OnMouseUp(MouseUpEvent e)
{
lastScreenSpaceMousePosition = e.ScreenSpaceMousePosition;
return base.OnMouseUp(e);
}
protected override bool OnMouseMove(MouseMoveEvent e)
{
lastScreenSpaceMousePosition = e.ScreenSpaceMousePosition;

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Osu.UI;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Overlays.Settings;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Osu.Edit;
@ -137,7 +138,7 @@ namespace osu.Game.Rulesets.Osu
}
}
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o };
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetOsu };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap);

View File

@ -292,7 +292,6 @@ namespace osu.Game.Rulesets.Osu.Replays
{
// We add intermediate frames for spinning / following a slider here.
case Spinner spinner:
{
Vector2 difference = startPosition - SPINNER_CENTRE;
float radius = difference.Length;
@ -315,9 +314,7 @@ namespace osu.Game.Rulesets.Osu.Replays
endFrame.Position = endPosition;
break;
}
case Slider slider:
{
for (double j = FrameDelay; j < slider.Duration; j += FrameDelay)
{
Vector2 pos = slider.StackedPositionAt(j / slider.Duration);
@ -326,7 +323,6 @@ namespace osu.Game.Rulesets.Osu.Replays
AddFrameToReplay(new OsuReplayFrame(slider.EndTime, new Vector2(slider.StackedEndPosition.X, slider.StackedEndPosition.Y), action));
break;
}
}
// We only want to let go of our button if we are at the end of the current replay. Otherwise something is still going on after us so we need to keep the button pressed!

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Input.StateChanges;
using osu.Framework.MathUtils;
@ -24,10 +25,14 @@ namespace osu.Game.Rulesets.Osu.Replays
{
get
{
if (!HasFrames)
var frame = CurrentFrame;
if (frame == null)
return null;
return Interpolation.ValueAt(CurrentTime, CurrentFrame.Position, NextFrame.Position, CurrentFrame.Time, NextFrame.Time);
Debug.Assert(CurrentTime != null);
return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position;
}
}
@ -41,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Replays
},
new ReplayState<OsuAction>
{
PressedActions = CurrentFrame.Actions
PressedActions = CurrentFrame?.Actions ?? new List<OsuAction>()
}
};
}

View File

@ -6,7 +6,6 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings;
using osu.Game.Beatmaps;
@ -14,10 +13,11 @@ using osu.Game.Configuration;
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Osu.UI.Cursor
{
public class GameplayCursorContainer : CursorContainer, IKeyBindingHandler<OsuAction>
public class OsuCursorContainer : GameplayCursorContainer, IKeyBindingHandler<OsuAction>
{
protected override Drawable CreateCursor() => new OsuCursor();
@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
private readonly Container<Drawable> fadeContainer;
public GameplayCursorContainer()
public OsuCursorContainer()
{
InternalChild = fadeContainer = new Container
{

View File

@ -32,7 +32,9 @@ namespace osu.Game.Rulesets.Osu.UI
protected override PassThroughInputManager CreateInputManager() => new OsuInputManager(Ruleset.RulesetInfo);
public override DrawableHitObject<OsuHitObject> GetVisualRepresentation(OsuHitObject h)
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new OsuPlayfieldAdjustmentContainer();
public override DrawableHitObject<OsuHitObject> CreateDrawableRepresentation(OsuHitObject h)
{
switch (h)
{

View File

@ -10,7 +10,6 @@ using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects.Drawables.Connections;
using osu.Game.Rulesets.UI;
using System.Linq;
using osu.Framework.Graphics.Cursor;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.UI.Cursor;
@ -24,41 +23,28 @@ namespace osu.Game.Rulesets.Osu.UI
public static readonly Vector2 BASE_SIZE = new Vector2(512, 384);
private readonly PlayfieldAdjustmentContainer adjustmentContainer;
protected override Container CursorTargetContainer => adjustmentContainer;
protected override CursorContainer CreateCursor() => new GameplayCursorContainer();
protected override GameplayCursorContainer CreateCursor() => new OsuCursorContainer();
public OsuPlayfield()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Size = new Vector2(0.75f);
InternalChild = adjustmentContainer = new PlayfieldAdjustmentContainer
InternalChildren = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
connectionLayer = new FollowPointRenderer
{
connectionLayer = new FollowPointRenderer
{
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
judgementLayer = new JudgementContainer<DrawableOsuJudgement>
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
HitObjectContainer,
approachCircles = new ApproachCircleProxyContainer
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
},
}
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
judgementLayer = new JudgementContainer<DrawableOsuJudgement>
{
RelativeSizeAxes = Axes.Both,
Depth = 1,
},
HitObjectContainer,
approachCircles = new ApproachCircleProxyContainer
{
RelativeSizeAxes = Axes.Both,
Depth = -1,
},
};
}

View File

@ -3,17 +3,23 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.UI;
using osuTK;
namespace osu.Game.Rulesets.Osu.UI
{
public class PlayfieldAdjustmentContainer : Container
public class OsuPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
protected override Container<Drawable> Content => content;
private readonly Container content;
public PlayfieldAdjustmentContainer()
public OsuPlayfieldAdjustmentContainer()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
Size = new Vector2(0.75f);
InternalChild = new Container
{
Anchor = Anchor.Centre,

View File

@ -3,8 +3,8 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects;
namespace osu.Game.Rulesets.Taiko.Beatmaps
@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
{
Name = @"Hit Count",
Content = hits.ToString(),
Icon = FontAwesome.fa_circle_o
Icon = FontAwesome.CircleOutline
},
new BeatmapStatistic
{
Name = @"Drumroll Count",
Content = drumrolls.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
},
new BeatmapStatistic
{
Name = @"Swell Count",
Content = swells.ToString(),
Icon = FontAwesome.fa_circle
Icon = FontAwesome.Circle
}
};
}

View File

@ -44,17 +44,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Y;
Width = tracker_width;
InternalChildren = new[]
AddInternal(Tracker = new Box
{
Tracker = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(0.5f, 0),
Alpha = 0.75f
}
};
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
EdgeSmoothness = new Vector2(0.5f, 0),
Alpha = 0.75f
});
}
protected override void UpdateState(ArmedState state)

View File

@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
protected DrawableTaikoHitObject(TaikoHitObject hitObject)
: base(hitObject)
{
InternalChildren = new[]
AddRangeInternal(new[]
{
nonProxiedContent = new Container
{
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Child = Content = new Container { RelativeSizeAxes = Axes.Both }
},
proxiedContent = new ProxiedContentContainer { RelativeSizeAxes = Axes.Both }
};
});
}
/// <summary>

View File

@ -4,7 +4,7 @@
using osuTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
{
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
new SpriteIcon
{
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.fa_asterisk,
Icon = FontAwesome.Asterisk,
Shadow = false
}
};

View File

@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Taiko.Replays
protected override bool IsImportant(TaikoReplayFrame frame) => frame.Actions.Any();
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<TaikoAction> { PressedActions = CurrentFrame.Actions } };
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<TaikoAction> { PressedActions = CurrentFrame?.Actions ?? new List<TaikoAction>() } };
}
}

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Taiko.UI;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Rulesets.Taiko.Objects;
@ -114,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko
public override string ShortName => "taiko";
public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o };
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetTaiko };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap);

View File

@ -81,11 +81,13 @@ namespace osu.Game.Rulesets.Taiko.UI
public override ScoreProcessor CreateScoreProcessor() => new TaikoScoreProcessor(this);
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer();
protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
protected override Playfield CreatePlayfield() => new TaikoPlayfield(Beatmap.ControlPointInfo);
public override DrawableHitObject<TaikoHitObject> GetVisualRepresentation(TaikoHitObject h)
public override DrawableHitObject<TaikoHitObject> CreateDrawableRepresentation(TaikoHitObject h)
{
switch (h)
{

View File

@ -55,143 +55,137 @@ namespace osu.Game.Rulesets.Taiko.UI
public TaikoPlayfield(ControlPointInfo controlPoints)
{
InternalChild = new PlayfieldAdjustmentContainer
InternalChildren = new Drawable[]
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
backgroundContainer = new Container
{
backgroundContainer = new Container
Name = "Transparent playfield background",
RelativeSizeAxes = Axes.Both,
Masking = true,
EdgeEffect = new EdgeEffectParameters
{
Name = "Transparent playfield background",
RelativeSizeAxes = Axes.Both,
Masking = true,
EdgeEffect = new EdgeEffectParameters
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.2f),
Radius = 5,
},
Children = new Drawable[]
{
background = new Box
{
Type = EdgeEffectType.Shadow,
Colour = Color4.Black.Opacity(0.2f),
Radius = 5,
RelativeSizeAxes = Axes.Both,
Alpha = 0.6f
},
Children = new Drawable[]
{
background = new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0.6f
},
}
},
new Container
{
Name = "Right area",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = left_area_size },
Children = new Drawable[]
{
new Container
{
Name = "Masked elements before hit objects",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
Masking = true,
Children = new Drawable[]
{
hitExplosionContainer = new Container<HitExplosion>
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Blending = BlendingMode.Additive,
},
HitTarget = new HitTarget
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit
}
}
},
barlineContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }
},
new Container
{
Name = "Hit objects",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
Masking = true,
Child = HitObjectContainer
},
kiaiExplosionContainer = new Container<KiaiHitExplosion>
{
Name = "Kiai hit explosions",
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive
},
judgementContainer = new JudgementContainer<DrawableTaikoJudgement>
{
Name = "Judgements",
RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive
},
}
},
overlayBackgroundContainer = new Container
{
Name = "Left overlay",
RelativeSizeAxes = Axes.Y,
Size = new Vector2(left_area_size, 1),
Children = new Drawable[]
{
overlayBackground = new Box
{
RelativeSizeAxes = Axes.Both,
},
new InputDrum(controlPoints)
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Scale = new Vector2(0.9f),
Margin = new MarginPadding { Right = 20 }
},
new Box
{
Anchor = Anchor.TopRight,
RelativeSizeAxes = Axes.Y,
Width = 10,
Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
},
}
},
new Container
{
Name = "Border",
RelativeSizeAxes = Axes.Both,
Masking = true,
MaskingSmoothness = 0,
BorderThickness = 2,
AlwaysPresent = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
},
topLevelHitContainer = new Container
{
Name = "Top level hit objects",
RelativeSizeAxes = Axes.Both,
}
},
new Container
{
Name = "Right area",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = left_area_size },
Children = new Drawable[]
{
new Container
{
Name = "Masked elements before hit objects",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
Masking = true,
Children = new Drawable[]
{
hitExplosionContainer = new Container<HitExplosion>
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Blending = BlendingMode.Additive,
},
HitTarget = new HitTarget
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit
}
}
},
barlineContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET }
},
new Container
{
Name = "Hit objects",
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = HIT_TARGET_OFFSET },
Masking = true,
Child = HitObjectContainer
},
kiaiExplosionContainer = new Container<KiaiHitExplosion>
{
Name = "Kiai hit explosions",
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive
},
judgementContainer = new JudgementContainer<DrawableTaikoJudgement>
{
Name = "Judgements",
RelativeSizeAxes = Axes.Y,
Margin = new MarginPadding { Left = HIT_TARGET_OFFSET },
Blending = BlendingMode.Additive
},
}
},
overlayBackgroundContainer = new Container
{
Name = "Left overlay",
RelativeSizeAxes = Axes.Y,
Size = new Vector2(left_area_size, 1),
Children = new Drawable[]
{
overlayBackground = new Box
{
RelativeSizeAxes = Axes.Both,
},
new InputDrum(controlPoints)
{
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Scale = new Vector2(0.9f),
Margin = new MarginPadding { Right = 20 }
},
new Box
{
Anchor = Anchor.TopRight,
RelativeSizeAxes = Axes.Y,
Width = 10,
Colour = Framework.Graphics.Colour.ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.6f), Color4.Black.Opacity(0)),
},
}
},
new Container
{
Name = "Border",
RelativeSizeAxes = Axes.Both,
Masking = true,
MaskingSmoothness = 0,
BorderThickness = 2,
AlwaysPresent = true,
Children = new[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
AlwaysPresent = true
}
}
},
topLevelHitContainer = new Container
{
Name = "Top level hit objects",
RelativeSizeAxes = Axes.Both,
}
};
}

View File

@ -1,16 +1,23 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Game.Rulesets.UI;
using osuTK;
namespace osu.Game.Rulesets.Taiko.UI
{
public class PlayfieldAdjustmentContainer : Container
public class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
private const float default_aspect = 16f / 9f;
public TaikoPlayfieldAdjustmentContainer()
{
Anchor = Anchor.CentreLeft;
Origin = Anchor.CentreLeft;
}
protected override void Update()
{
base.Update();

View File

@ -29,28 +29,28 @@ namespace osu.Game.Tests.Beatmaps.Formats
StoryboardLayer background = storyboard.Layers.FirstOrDefault(l => l.Depth == 3);
Assert.IsNotNull(background);
Assert.AreEqual(16, background.Elements.Count());
Assert.AreEqual(16, background.Elements.Count);
Assert.IsTrue(background.EnabledWhenFailing);
Assert.IsTrue(background.EnabledWhenPassing);
Assert.AreEqual("Background", background.Name);
StoryboardLayer fail = storyboard.Layers.FirstOrDefault(l => l.Depth == 2);
Assert.IsNotNull(fail);
Assert.AreEqual(0, fail.Elements.Count());
Assert.AreEqual(0, fail.Elements.Count);
Assert.IsTrue(fail.EnabledWhenFailing);
Assert.IsFalse(fail.EnabledWhenPassing);
Assert.AreEqual("Fail", fail.Name);
StoryboardLayer pass = storyboard.Layers.FirstOrDefault(l => l.Depth == 1);
Assert.IsNotNull(pass);
Assert.AreEqual(0, pass.Elements.Count());
Assert.AreEqual(0, pass.Elements.Count);
Assert.IsFalse(pass.EnabledWhenFailing);
Assert.IsTrue(pass.EnabledWhenPassing);
Assert.AreEqual("Pass", pass.Name);
StoryboardLayer foreground = storyboard.Layers.FirstOrDefault(l => l.Depth == 0);
Assert.IsNotNull(foreground);
Assert.AreEqual(151, foreground.Elements.Count());
Assert.AreEqual(151, foreground.Elements.Count);
Assert.IsTrue(foreground.EnabledWhenFailing);
Assert.IsTrue(foreground.EnabledWhenPassing);
Assert.AreEqual("Foreground", foreground.Name);
@ -62,7 +62,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual(15, spriteCount);
Assert.AreEqual(1, animationCount);
Assert.AreEqual(0, sampleCount);
Assert.AreEqual(background.Elements.Count(), spriteCount + animationCount + sampleCount);
Assert.AreEqual(background.Elements.Count, spriteCount + animationCount + sampleCount);
var sprite = background.Elements.ElementAt(0) as StoryboardSprite;
Assert.NotNull(sprite);
@ -70,9 +70,9 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual(new Vector2(320, 240), sprite.InitialPosition);
Assert.IsTrue(sprite.IsDrawable);
Assert.AreEqual(Anchor.Centre, sprite.Origin);
Assert.AreEqual("SB/lyric/ja-21.png", sprite.Path);
Assert.AreEqual("SB/black.jpg", sprite.Path);
var animation = background.Elements.ElementAt(12) as StoryboardAnimation;
var animation = background.Elements.OfType<StoryboardAnimation>().First();
Assert.NotNull(animation);
Assert.AreEqual(141175, animation.EndTime);
Assert.AreEqual(10, animation.FrameCount);

View File

@ -0,0 +1,284 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using NUnit.Framework;
using osu.Game.Replays;
using osu.Game.Rulesets.Replays;
namespace osu.Game.Tests.NonVisual
{
[TestFixture]
public class FramedReplayinputHandlerTest
{
private Replay replay;
private TestInputHandler handler;
[SetUp]
public void SetUp()
{
handler = new TestInputHandler(replay = new Replay
{
Frames = new List<ReplayFrame>
{
new TestReplayFrame(0),
new TestReplayFrame(1000),
new TestReplayFrame(2000),
new TestReplayFrame(3000, true),
new TestReplayFrame(4000, true),
new TestReplayFrame(5000, true),
new TestReplayFrame(7000, true),
new TestReplayFrame(8000),
}
});
}
[Test]
public void TestNormalPlayback()
{
Assert.IsNull(handler.CurrentFrame);
confirmCurrentFrame(null);
confirmNextFrame(0);
setTime(0, 0);
confirmCurrentFrame(0);
confirmNextFrame(1);
//if we hit the first frame perfectly, time should progress to it.
setTime(1000, 1000);
confirmCurrentFrame(1);
confirmNextFrame(2);
//in between non-important frames should progress based on input.
setTime(1200, 1200);
confirmCurrentFrame(1);
setTime(1400, 1400);
confirmCurrentFrame(1);
// progressing beyond the next frame should force time to that frame once.
setTime(2200, 2000);
confirmCurrentFrame(2);
// second attempt should progress to input time
setTime(2200, 2200);
confirmCurrentFrame(2);
// entering important section
setTime(3000, 3000);
confirmCurrentFrame(3);
// cannot progress within
setTime(3500, null);
confirmCurrentFrame(3);
setTime(4000, 4000);
confirmCurrentFrame(4);
// still cannot progress
setTime(4500, null);
confirmCurrentFrame(4);
setTime(5200, 5000);
confirmCurrentFrame(5);
// important section AllowedImportantTimeSpan allowance
setTime(5200, 5200);
confirmCurrentFrame(5);
setTime(7200, 7000);
confirmCurrentFrame(6);
setTime(7200, null);
confirmCurrentFrame(6);
// exited important section
setTime(8200, 8000);
confirmCurrentFrame(7);
confirmNextFrame(null);
setTime(8200, 8200);
confirmCurrentFrame(7);
confirmNextFrame(null);
}
[Test]
public void TestIntroTime()
{
setTime(-1000, -1000);
confirmCurrentFrame(null);
confirmNextFrame(0);
setTime(-500, -500);
confirmCurrentFrame(null);
confirmNextFrame(0);
setTime(0, 0);
confirmCurrentFrame(0);
confirmNextFrame(1);
}
[Test]
public void TestBasicRewind()
{
setTime(2800, 0);
setTime(2800, 1000);
setTime(2800, 2000);
setTime(2800, 2800);
confirmCurrentFrame(2);
confirmNextFrame(3);
// pivot without crossing a frame boundary
setTime(2700, 2700);
confirmCurrentFrame(2);
confirmNextFrame(1);
// cross current frame boundary; should not yet update frame
setTime(1980, 1980);
confirmCurrentFrame(2);
confirmNextFrame(1);
setTime(1200, 1200);
confirmCurrentFrame(2);
confirmNextFrame(1);
//ensure each frame plays out until start
setTime(-500, 1000);
confirmCurrentFrame(1);
confirmNextFrame(0);
setTime(-500, 0);
confirmCurrentFrame(0);
confirmNextFrame(null);
setTime(-500, -500);
confirmCurrentFrame(0);
confirmNextFrame(null);
}
[Test]
public void TestRewindInsideImportantSection()
{
// fast forward to important section
while (handler.SetFrameFromTime(3000) != null)
{
}
setTime(4000, 4000);
confirmCurrentFrame(4);
confirmNextFrame(5);
setTime(3500, null);
confirmCurrentFrame(4);
confirmNextFrame(3);
setTime(3000, 3000);
confirmCurrentFrame(3);
confirmNextFrame(2);
setTime(3500, null);
confirmCurrentFrame(3);
confirmNextFrame(4);
setTime(4000, 4000);
confirmCurrentFrame(4);
confirmNextFrame(5);
setTime(4500, null);
confirmCurrentFrame(4);
confirmNextFrame(5);
setTime(4000, null);
confirmCurrentFrame(4);
confirmNextFrame(5);
setTime(3500, null);
confirmCurrentFrame(4);
confirmNextFrame(3);
setTime(3000, 3000);
confirmCurrentFrame(3);
confirmNextFrame(2);
}
[Test]
public void TestRewindOutOfImportantSection()
{
// fast forward to important section
while (handler.SetFrameFromTime(3500) != null)
{
}
confirmCurrentFrame(3);
confirmNextFrame(4);
setTime(3200, null);
// next frame doesn't change even though direction reversed, because of important section.
confirmCurrentFrame(3);
confirmNextFrame(4);
setTime(3000, null);
confirmCurrentFrame(3);
confirmNextFrame(4);
setTime(2800, 2800);
confirmCurrentFrame(3);
confirmNextFrame(2);
}
private void setTime(double set, double? expect)
{
Assert.AreEqual(expect, handler.SetFrameFromTime(set));
}
private void confirmCurrentFrame(int? frame)
{
if (frame.HasValue)
{
Assert.IsNotNull(handler.CurrentFrame);
Assert.AreEqual(replay.Frames[frame.Value].Time, handler.CurrentFrame.Time);
}
else
{
Assert.IsNull(handler.CurrentFrame);
}
}
private void confirmNextFrame(int? frame)
{
if (frame.HasValue)
{
Assert.IsNotNull(handler.NextFrame);
Assert.AreEqual(replay.Frames[frame.Value].Time, handler.NextFrame.Time);
}
else
{
Assert.IsNull(handler.NextFrame);
}
}
private class TestReplayFrame : ReplayFrame
{
public readonly bool IsImportant;
public TestReplayFrame(double time, bool isImportant = false)
: base(time)
{
IsImportant = isImportant;
}
}
private class TestInputHandler : FramedReplayInputHandler<TestReplayFrame>
{
public TestInputHandler(Replay replay)
: base(replay)
{
}
protected override double AllowedImportantTimeSpan => 1000;
protected override bool IsImportant(TestReplayFrame frame) => frame.IsImportant;
}
}
}

View File

@ -92,7 +92,7 @@ namespace osu.Game.Tests.Visual.Background
public void PlayerLoaderSettingsHoverTest()
{
setupUserSettings();
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer())));
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer { BlockLoad = true })));
AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
AddStep("Trigger background preview", () =>
@ -255,14 +255,8 @@ namespace osu.Game.Tests.Visual.Background
{
setupUserSettings();
AddStep("Start player loader", () =>
{
songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer
{
AllowPause = allowPause,
Ready = true,
}));
});
AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer(allowPause))));
AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
AddUntilStep("Wait for player to load", () => player.IsLoaded);
@ -351,21 +345,27 @@ namespace osu.Game.Tests.Visual.Background
public UserDimContainer CurrentStoryboardContainer => StoryboardContainer;
// Whether or not the player should be allowed to load.
public bool Ready;
public bool BlockLoad;
public Bindable<bool> StoryboardEnabled;
public readonly Bindable<bool> ReplacesBackground = new Bindable<bool>();
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
public TestPlayer(bool allowPause = true)
: base(allowPause)
{
}
public bool IsStoryboardVisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha == 1;
public bool IsStoryboardInvisible() => ((TestUserDimContainer)CurrentStoryboardContainer).CurrentAlpha <= 1;
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
private void load(OsuConfigManager config, CancellationToken token)
{
while (!Ready)
while (BlockLoad && !token.IsCancellationRequested)
Thread.Sleep(1);
StoryboardEnabled = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
ReplacesBackground.BindTo(Background.StoryboardReplacesBackground);
DrawableRuleset.IsPaused.BindTo(IsPaused);

View File

@ -15,12 +15,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Player CreatePlayer(Ruleset ruleset)
{
Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return new ScoreAccessiblePlayer
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
};
return new ScoreAccessiblePlayer();
}
protected override void AddCheckSteps()
@ -33,6 +28,11 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
public new HUDOverlay HUDOverlay => base.HUDOverlay;
public ScoreAccessiblePlayer()
: base(false, false)
{
}
}
}
}

View File

@ -20,13 +20,13 @@ namespace osu.Game.Tests.Visual.Gameplay
{
typeof(KeyCounterKeyboard),
typeof(KeyCounterMouse),
typeof(KeyCounterCollection)
typeof(KeyCounterDisplay)
};
public TestCaseKeyCounter()
{
KeyCounterKeyboard rewindTestKeyCounterKeyboard;
KeyCounterCollection kc = new KeyCounterCollection
KeyCounterDisplay kc = new KeyCounterDisplay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,

View File

@ -26,12 +26,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
Beatmap.Value = new DummyWorkingBeatmap(game);
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
})));
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player(false, false))));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
@ -47,12 +42,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
SlowLoadPlayer slow = null;
stack.Push(loader = new PlayerLoader(() => slow = new SlowLoadPlayer
{
AllowPause = false,
AllowLeadIn = false,
AllowResults = false,
}));
stack.Push(loader = new PlayerLoader(() => slow = new SlowLoadPlayer(false, false)));
Scheduler.AddDelayed(() => slow.Ready = true, 5000);
});
@ -64,6 +54,11 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public bool Ready;
public SlowLoadPlayer(bool allowPause = true, bool showResults = true)
: base(allowPause, showResults)
{
}
[BackgroundDependencyLoader]
private void load()
{

View File

@ -170,12 +170,12 @@ namespace osu.Game.Tests.Visual.Gameplay
{
Origin = Anchor.Centre;
InternalChild = new Box
AddInternal(new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both
};
});
switch (direction)
{
@ -205,7 +205,7 @@ namespace osu.Game.Tests.Visual.Gameplay
Origin = Anchor.Centre;
AutoSizeAxes = Axes.Both;
InternalChild = new Box { Size = new Vector2(75) };
AddInternal(new Box { Size = new Vector2(75) });
}
protected override void UpdateState(ArmedState state)

View File

@ -1,7 +1,9 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Threading;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
@ -12,59 +14,85 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Menus
{
[TestFixture]
public class TestCaseLoaderAnimation : OsuTestCase
public class TestCaseLoaderAnimation : ScreenTestCase
{
private TestLoader loader;
protected override void LoadComplete()
[Cached]
private OsuLogo logo;
public TestCaseLoaderAnimation()
{
base.LoadComplete();
// required to preload the logo in a headless run (so it doesn't delay the loading itself).
Add(new OsuLogo());
Child = logo = new OsuLogo { Depth = float.MinValue };
}
[Test]
public void TestInstantLoad()
{
bool logoVisible = false;
AddStep("almost instant display", () => Child = loader = new TestLoader(250));
AddUntilStep("loaded", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded;
});
AddAssert("logo not visible", () => !logoVisible);
AddStep("short load", () => Child = loader = new TestLoader(800));
AddUntilStep("loaded", () =>
AddStep("begin loading", () =>
{
loader = new TestLoader();
loader.AllowLoad.Set();
LoadScreen(loader);
});
AddAssert("loaded", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded;
});
AddAssert("logo visible", () => logoVisible);
AddAssert("logo was not visible", () => !logoVisible);
}
[Test]
public void TestShortLoad()
{
bool logoVisible = false;
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
AddWaitStep("wait", 2);
AddStep("finish loading", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
loader.AllowLoad.Set();
});
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
AddAssert("logo was visible", () => logoVisible);
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
}
AddStep("longer load", () => Child = loader = new TestLoader(1400));
AddUntilStep("loaded", () =>
[Test]
public void TestLongLoad()
{
bool logoVisible = false;
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
AddWaitStep("wait", 10);
AddStep("finish loading", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded;
loader.AllowLoad.Set();
});
AddAssert("logo visible", () => logoVisible);
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
AddAssert("logo was visible", () => logoVisible);
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
}
private class TestLoader : Loader
{
private readonly double delay;
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim();
public OsuLogo Logo;
private TestScreen screen;
public bool ScreenLoaded => screen.IsCurrentScreen();
public TestLoader(double delay)
{
this.delay = delay;
}
protected override void LogoArriving(OsuLogo logo, bool resuming)
{
Logo = logo;
@ -72,25 +100,18 @@ namespace osu.Game.Tests.Visual.Menus
}
protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen();
protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay);
protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(AllowLoad);
private class TestShaderPrecompiler : ShaderPrecompiler
{
private readonly double delay;
private double startTime;
private readonly ManualResetEventSlim allowLoad;
public TestShaderPrecompiler(double delay)
public TestShaderPrecompiler(ManualResetEventSlim allowLoad)
{
this.delay = delay;
this.allowLoad = allowLoad;
}
protected override void LoadComplete()
{
base.LoadComplete();
startTime = Time.Current;
}
protected override bool AllLoaded => Time.Current > startTime + delay;
protected override bool AllLoaded => allowLoad.IsSet;
}
private class TestScreen : OsuScreen

View File

@ -27,7 +27,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
[Cached(Type = typeof(IRoomManager))]
private TestRoomManager roomManager = new TestRoomManager();
public TestCaseLoungeRoomsContainer()
[BackgroundDependencyLoader]
private void load()
{
RoomsContainer container;

View File

@ -2,7 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Screens.Select.Options;
using osuTK.Graphics;
using osuTK.Input;
@ -16,10 +16,10 @@ namespace osu.Game.Tests.Visual.SongSelect
{
var overlay = new BeatmapOptionsOverlay();
overlay.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, Color4.Purple, null, Key.Number1);
overlay.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, Color4.Purple, null, Key.Number2);
overlay.AddButton(@"Edit", @"Beatmap", FontAwesome.fa_pencil, Color4.Yellow, null, Key.Number3);
overlay.AddButton(@"Delete", @"Beatmap", FontAwesome.fa_trash, Color4.Pink, null, Key.Number4, float.MaxValue);
overlay.AddButton(@"Remove", @"from unplayed", FontAwesome.TimesCircleOutline, Color4.Purple, null, Key.Number1);
overlay.AddButton(@"Clear", @"local scores", FontAwesome.Eraser, Color4.Purple, null, Key.Number2);
overlay.AddButton(@"Edit", @"Beatmap", FontAwesome.Pencil, Color4.Yellow, null, Key.Number3);
overlay.AddButton(@"Delete", @"Beatmap", FontAwesome.Trash, Color4.Pink, null, Key.Number4, float.MaxValue);
Add(overlay);

View File

@ -9,7 +9,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.BeatmapSet.Scores;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
@ -44,9 +43,9 @@ namespace osu.Game.Tests.Visual.SongSelect
}
};
IEnumerable<APIScoreInfo> scores = new[]
IEnumerable<ScoreInfo> scores = new[]
{
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -69,7 +68,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1234567890,
Accuracy = 1,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -91,7 +90,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1234789,
Accuracy = 0.9997,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -112,7 +111,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 12345678,
Accuracy = 0.9854,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -132,7 +131,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1234567,
Accuracy = 0.8765,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -157,9 +156,9 @@ namespace osu.Game.Tests.Visual.SongSelect
s.Statistics.Add(HitResult.Meh, RNG.Next(2000));
}
IEnumerable<APIScoreInfo> anotherScores = new[]
IEnumerable<ScoreInfo> anotherScores = new[]
{
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -181,7 +180,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1234789,
Accuracy = 0.9997,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -204,7 +203,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 1234567890,
Accuracy = 1,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -220,7 +219,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 123456,
Accuracy = 0.6543,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -241,7 +240,7 @@ namespace osu.Game.Tests.Visual.SongSelect
TotalScore = 12345678,
Accuracy = 0.9854,
},
new APIScoreInfo
new ScoreInfo
{
User = new User
{
@ -269,7 +268,7 @@ namespace osu.Game.Tests.Visual.SongSelect
s.Statistics.Add(HitResult.Meh, RNG.Next(2000));
}
var topScoreInfo = new APIScoreInfo
var topScoreInfo = new ScoreInfo
{
User = new User
{

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using osu.Framework.Allocation;
using osu.Game.Screens.Tournament;
using osu.Game.Screens.Tournament.Teams;
@ -11,7 +12,8 @@ namespace osu.Game.Tests.Visual.Tournament
[Description("for tournament use")]
public class TestCaseDrawings : ScreenTestCase
{
public TestCaseDrawings()
[BackgroundDependencyLoader]
private void load()
{
LoadScreen(new Drawings
{

View File

@ -2,7 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("dialog #1", () => overlay.Push(new PopupDialog
{
Icon = FontAwesome.fa_trash_o,
Icon = FontAwesome.TrashOutline,
HeaderText = @"Confirm deletion of",
BodyText = @"Ayase Rie - Yuima-ru*World TVver.",
Buttons = new PopupDialogButton[]
@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("dialog #2", () => overlay.Push(new PopupDialog
{
Icon = FontAwesome.fa_gear,
Icon = FontAwesome.Gear,
HeaderText = @"What do you want to do with",
BodyText = "Camellia as \"Bang Riot\" - Blastix Riotz",
Buttons = new PopupDialogButton[]

View File

@ -111,7 +111,7 @@ namespace osu.Game.Tests.Visual.UserInterface
button.Anchor = Anchor.Centre;
button.Origin = Anchor.Centre;
button.Icon = FontAwesome.fa_osu_osu_o;
button.Icon = OsuIcon.RulesetOsu;
}
}
}

View File

@ -0,0 +1,73 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Reflection;
using NUnit.Framework;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestCaseOsuIcon : TestCase
{
public TestCaseOsuIcon()
{
FillFlowContainer<Icon> flow;
AddRange(new Drawable[]
{
new Box
{
Colour = Color4.Teal,
RelativeSizeAxes = Axes.Both,
},
new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
Child = flow = new FillFlowContainer<Icon>
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Full,
},
}
});
foreach (var p in typeof(OsuIcon).GetProperties(BindingFlags.Public | BindingFlags.Static))
flow.Add(new Icon($"{nameof(OsuIcon)}.{p.Name}", (IconUsage)p.GetValue(null)));
AddStep("toggle shadows", () => flow.Children.ForEach(i => i.SpriteIcon.Shadow = !i.SpriteIcon.Shadow));
AddStep("change icons", () => flow.Children.ForEach(i => i.SpriteIcon.Icon = new IconUsage((char)(i.SpriteIcon.Icon.Icon + 1))));
}
private class Icon : Container, IHasTooltip
{
public string TooltipText { get; }
public SpriteIcon SpriteIcon { get; }
public Icon(string name, IconUsage icon)
{
TooltipText = name;
AutoSizeAxes = Axes.Both;
Child = SpriteIcon = new SpriteIcon
{
Icon = icon,
Size = new Vector2(60),
};
}
}
}
}

View File

@ -3,7 +3,7 @@
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Overlays.Dialog;
namespace osu.Game.Tests.Visual.UserInterface
@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface
{
RelativeSizeAxes = Axes.Both,
State = Framework.Graphics.Containers.Visibility.Visible,
Icon = FontAwesome.fa_assistive_listening_systems,
Icon = FontAwesome.AssistiveListeningSystems,
HeaderText = @"This is a test popup",
BodyText = "I can say lots of stuff and even wrap my words!",
Buttons = new PopupDialogButton[]

View File

@ -1,55 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics;
using osuTK;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
public class TestCaseTextAwesome : OsuTestCase
{
public TestCaseTextAwesome()
{
FillFlowContainer flow;
Add(new ScrollContainer
{
RelativeSizeAxes = Axes.Both,
Child = flow = new FillFlowContainer
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Full,
},
});
foreach (FontAwesome fa in Enum.GetValues(typeof(FontAwesome)))
flow.Add(new Icon(fa));
}
private class Icon : Container, IHasTooltip
{
public string TooltipText { get; }
public Icon(FontAwesome fa)
{
TooltipText = fa.ToString();
AutoSizeAxes = Axes.Both;
Child = new SpriteIcon
{
Icon = fa,
Size = new Vector2(60),
};
}
}
}
}

View File

@ -1,13 +1,13 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Beatmaps
{
public class BeatmapStatistic
{
public FontAwesome Icon;
public IconUsage Icon;
public string Content;
public string Name;
}

View File

@ -7,7 +7,7 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets;
using osuTK;
@ -60,7 +60,7 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.fa_question_circle_o }
Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.QuestionCircleOutline }
}
};
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
@ -38,6 +39,10 @@ namespace osu.Game.Beatmaps.Formats
{
this.storyboard = storyboard;
base.ParseStreamInto(stream, storyboard);
// OrderBy is used to guarantee that the parsing order of elements with equal start times is maintained (stably-sorted)
foreach (StoryboardLayer layer in storyboard.Layers)
layer.Elements = layer.Elements.OrderBy(h => h.StartTime).ToList();
}
protected override void ParseLine(Storyboard storyboard, Section section, string line)

View File

@ -55,7 +55,7 @@ namespace osu.Game.Configuration
// Input
Set(OsuSetting.MenuCursorSize, 1.0, 0.5f, 2, 0.01);
Set(OsuSetting.GameplayCursorSize, 1.0, 0.5f, 2, 0.01);
Set(OsuSetting.GameplayCursorSize, 1.0, 0.1f, 2, 0.01);
Set(OsuSetting.AutoCursorSize, false);
Set(OsuSetting.MouseDisableButtons, false);

View File

@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers
showNotImplementedError = () => notifications?.Post(new SimpleNotification
{
Text = @"This link type is not yet supported!",
Icon = FontAwesome.fa_life_saver,
Icon = FontAwesome.LifeSaver,
});
}

View File

@ -21,6 +21,6 @@ namespace osu.Game.Graphics.Containers
public void AddArbitraryDrawable(Drawable drawable) => AddInternal(drawable);
public IEnumerable<Drawable> AddIcon(FontAwesome icon, Action<SpriteText> creationParameters = null) => AddText(((char)icon).ToString(), creationParameters);
public IEnumerable<Drawable> AddIcon(IconUsage icon, Action<SpriteText> creationParameters = null) => AddText(icon.Icon.ToString(), creationParameters);
}
}

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Screens.Play;
using osuTK;
using osuTK.Graphics;

View File

@ -5,7 +5,7 @@ using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics
{
public struct OsuFont
public static class OsuFont
{
/// <summary>
/// The default font size.

View File

@ -0,0 +1,94 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics
{
public static class OsuIcon
{
public static IconUsage Get(int icon) => new IconUsage((char)icon, "OsuFont");
// ruleset icons in circles
public static IconUsage RulesetOsu => Get(0xe000);
public static IconUsage RulesetMania => Get(0xe001);
public static IconUsage RulesetCatch => Get(0xe002);
public static IconUsage RulesetTaiko => Get(0xe003);
// ruleset icons without circles
public static IconUsage FilledCircle => Get(0xe004);
public static IconUsage CrossCircle => Get(0xe005);
public static IconUsage Logo => Get(0xe006);
public static IconUsage ChevronDownCircle => Get(0xe007);
public static IconUsage EditCircle => Get(0xe033);
public static IconUsage LeftCircle => Get(0xe034);
public static IconUsage RightCircle => Get(0xe035);
public static IconUsage Charts => Get(0xe036);
public static IconUsage Solo => Get(0xe037);
public static IconUsage Multi => Get(0xe038);
public static IconUsage Gear => Get(0xe039);
// misc icons
public static IconUsage Bat => Get(0xe008);
public static IconUsage Bubble => Get(0xe009);
public static IconUsage BubblePop => Get(0xe02e);
public static IconUsage Dice => Get(0xe011);
public static IconUsage Heart => Get(0xe02f);
public static IconUsage HeartBreak => Get(0xe030);
public static IconUsage Hot => Get(0xe031);
public static IconUsage ListSearch => Get(0xe032);
//osu! playstyles
public static IconUsage PlaystyleTablet => Get(0xe02a);
public static IconUsage PlaystyleMouse => Get(0xe029);
public static IconUsage PlaystyleKeyboard => Get(0xe02b);
public static IconUsage PlaystyleTouch => Get(0xe02c);
// osu! difficulties
public static IconUsage EasyOsu => Get(0xe015);
public static IconUsage NormalOsu => Get(0xe016);
public static IconUsage HardOsu => Get(0xe017);
public static IconUsage InsaneOsu => Get(0xe018);
public static IconUsage ExpertOsu => Get(0xe019);
// taiko difficulties
public static IconUsage EasyTaiko => Get(0xe01a);
public static IconUsage NormalTaiko => Get(0xe01b);
public static IconUsage HardTaiko => Get(0xe01c);
public static IconUsage InsaneTaiko => Get(0xe01d);
public static IconUsage ExpertTaiko => Get(0xe01e);
// fruits difficulties
public static IconUsage EasyFruits => Get(0xe01f);
public static IconUsage NormalFruits => Get(0xe020);
public static IconUsage HardFruits => Get(0xe021);
public static IconUsage InsaneFruits => Get(0xe022);
public static IconUsage ExpertFruits => Get(0xe023);
// mania difficulties
public static IconUsage EasyMania => Get(0xe024);
public static IconUsage NormalMania => Get(0xe025);
public static IconUsage HardMania => Get(0xe026);
public static IconUsage InsaneMania => Get(0xe027);
public static IconUsage ExpertMania => Get(0xe028);
// mod icons
public static IconUsage ModPerfect => Get(0xe049);
public static IconUsage ModAutopilot => Get(0xe03a);
public static IconUsage ModAuto => Get(0xe03b);
public static IconUsage ModCinema => Get(0xe03c);
public static IconUsage ModDoubletime => Get(0xe03d);
public static IconUsage ModEasy => Get(0xe03e);
public static IconUsage ModFlashlight => Get(0xe03f);
public static IconUsage ModHalftime => Get(0xe040);
public static IconUsage ModHardrock => Get(0xe041);
public static IconUsage ModHidden => Get(0xe042);
public static IconUsage ModNightcore => Get(0xe043);
public static IconUsage ModNofail => Get(0xe044);
public static IconUsage ModRelax => Get(0xe045);
public static IconUsage ModSpunout => Get(0xe046);
public static IconUsage ModSuddendeath => Get(0xe047);
public static IconUsage ModTarget => Get(0xe048);
public static IconUsage ModBg => Get(0xe04a);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ namespace osu.Game.Graphics.UserInterface
public BackButton()
{
Text = @"back";
Icon = FontAwesome.fa_osu_left_o;
Icon = OsuIcon.LeftCircle;
Anchor = Anchor.BottomLeft;
Origin = Anchor.BottomLeft;
}

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using System.Linq;
using osu.Framework.Graphics.Sprites;
namespace osu.Game.Graphics.UserInterface
{
@ -92,7 +93,7 @@ namespace osu.Game.Graphics.UserInterface
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreLeft,
Size = new Vector2(item_chevron_size),
Icon = FontAwesome.fa_chevron_right,
Icon = FontAwesome.ChevronRight,
Margin = new MarginPadding { Left = padding },
Alpha = 0f,
});

View File

@ -5,6 +5,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
using osuTK;
@ -25,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface
Size = new Vector2(12);
InternalChild = new SpriteIcon
{
Icon = FontAwesome.fa_external_link,
Icon = FontAwesome.ExternalLink,
RelativeSizeAxes = Axes.Both
};
}

View File

@ -4,6 +4,7 @@
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
namespace osu.Game.Graphics.UserInterface
@ -41,7 +42,7 @@ namespace osu.Game.Graphics.UserInterface
/// <summary>
/// The icon.
/// </summary>
public FontAwesome Icon
public IconUsage Icon
{
get => icon.Icon;
set => icon.Icon = value;

View File

@ -3,6 +3,7 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
@ -36,14 +37,14 @@ namespace osu.Game.Graphics.UserInterface
Position = new Vector2(1, 1),
Colour = Color4.Black,
Alpha = 0.4f,
Icon = FontAwesome.fa_circle_o_notch
Icon = FontAwesome.CircleONotch
},
spinner = new SpriteIcon
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Icon = FontAwesome.fa_circle_o_notch
Icon = FontAwesome.CircleONotch
}
};
}

View File

@ -179,7 +179,7 @@ namespace osu.Game.Graphics.UserInterface
Chevron = new SpriteIcon
{
AlwaysPresent = true,
Icon = FontAwesome.fa_chevron_right,
Icon = FontAwesome.ChevronRight,
Colour = Color4.Black,
Alpha = 0.5f,
Size = new Vector2(8),
@ -244,7 +244,7 @@ namespace osu.Game.Graphics.UserInterface
},
Icon = new SpriteIcon
{
Icon = FontAwesome.fa_chevron_down,
Icon = FontAwesome.ChevronDown,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
Margin = new MarginPadding { Right = 4 },

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.Platform;
@ -107,7 +108,7 @@ namespace osu.Game.Graphics.UserInterface
public CapsWarning()
{
Icon = FontAwesome.fa_warning;
Icon = FontAwesome.Warning;
}
[BackgroundDependencyLoader]

View File

@ -254,7 +254,7 @@ namespace osu.Game.Graphics.UserInterface
{
new SpriteIcon
{
Icon = FontAwesome.fa_ellipsis_h,
Icon = FontAwesome.EllipsisH,
Size = new Vector2(14),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,

View File

@ -99,7 +99,7 @@ namespace osu.Game.Graphics.UserInterface
icon = new SpriteIcon
{
Size = new Vector2(14),
Icon = FontAwesome.fa_circle_o,
Icon = FontAwesome.CircleOutline,
Shadow = true,
},
},
@ -120,12 +120,12 @@ namespace osu.Game.Graphics.UserInterface
if (selected.NewValue)
{
fadeIn();
icon.Icon = FontAwesome.fa_check_circle_o;
icon.Icon = FontAwesome.CheckCircleOutline;
}
else
{
fadeOut();
icon.Icon = FontAwesome.fa_circle_o;
icon.Icon = FontAwesome.CircleOutline;
}
};
}

View File

@ -0,0 +1,80 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Graphics.UserInterface
{
public abstract class ScreenTitle : CompositeDrawable, IHasAccentColour
{
private readonly SpriteIcon iconSprite;
private readonly OsuSpriteText titleText, pageText;
protected IconUsage Icon
{
get => iconSprite.Icon;
set => iconSprite.Icon = value;
}
protected string Title
{
get => titleText.Text;
set => titleText.Text = value;
}
protected string Section
{
get => pageText.Text;
set => pageText.Text = value;
}
public Color4 AccentColour
{
get => pageText.Colour;
set => pageText.Colour = value;
}
protected ScreenTitle()
{
AutoSizeAxes = Axes.Both;
InternalChildren = new Drawable[]
{
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Spacing = new Vector2(10, 0),
Children = new Drawable[]
{
iconSprite = new SpriteIcon
{
Size = new Vector2(25),
},
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(6, 0),
Children = new[]
{
titleText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 25),
},
pageText = new OsuSpriteText
{
Font = OsuFont.GetFont(size: 25),
}
}
}
}
},
};
}
}
}

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