mirror of
https://github.com/ppy/osu.git
synced 2025-01-27 00:23:01 +08:00
Merge branch 'master' into fix-rank-display
This commit is contained in:
commit
288b3deb94
@ -1,5 +1,5 @@
|
||||
#addin "nuget:?package=CodeFileSanity&version=0.0.21"
|
||||
#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.3.4"
|
||||
#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2019.1.1"
|
||||
#tool "nuget:?package=NVika.MSBuild&version=1.0.1"
|
||||
var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First();
|
||||
|
||||
|
@ -77,6 +77,7 @@ namespace osu.Desktop
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Visible;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Hidden;
|
||||
@ -87,6 +88,7 @@ namespace osu.Desktop
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
base.SetHost(host);
|
||||
|
||||
if (host.Window is DesktopGameWindow desktopWindow)
|
||||
{
|
||||
desktopWindow.CursorState |= CursorState.Hidden;
|
||||
|
@ -95,6 +95,7 @@ namespace osu.Desktop.Overlays
|
||||
|
||||
var version = game.Version;
|
||||
var lastVersion = config.Get<string>(OsuSetting.Version);
|
||||
|
||||
if (game.IsDeployedBuild && version != lastVersion)
|
||||
{
|
||||
config.Set(OsuSetting.Version, version);
|
||||
|
@ -31,6 +31,7 @@ namespace osu.Desktop
|
||||
var importer = new ArchiveImportIPCChannel(host);
|
||||
// Restore the cwd so relative paths given at the command line work correctly
|
||||
Directory.SetCurrentDirectory(cwd);
|
||||
|
||||
foreach (var file in args)
|
||||
{
|
||||
Console.WriteLine(@"Importing {0}", file);
|
||||
|
@ -78,6 +78,7 @@ namespace osu.Desktop.Updater
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe"));
|
||||
break;
|
||||
|
||||
case RuntimeInfo.Platform.MacOsx:
|
||||
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip"));
|
||||
break;
|
||||
|
@ -175,7 +175,7 @@ namespace osu.Desktop.Updater
|
||||
|
||||
public SquirrelLogger()
|
||||
{
|
||||
var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "SquirrelSetupUpdater.log");
|
||||
var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location ?? Directory.GetCurrentDirectory()), "SquirrelSetupUpdater.log");
|
||||
if (File.Exists(file)) File.Delete(file);
|
||||
path = file;
|
||||
}
|
||||
|
@ -36,11 +36,13 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
yield return new ConvertValue((CatchHitObject)nested);
|
||||
|
||||
break;
|
||||
|
||||
case BananaShower shower:
|
||||
foreach (var nested in shower.NestedHitObjects)
|
||||
yield return new ConvertValue((CatchHitObject)nested);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
yield return new ConvertValue((CatchHitObject)hitObject);
|
||||
|
||||
|
@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
||||
|
||||
int index = 0;
|
||||
|
||||
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
{
|
||||
obj.IndexInBeatmap = index++;
|
||||
@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case JuiceStream juiceStream:
|
||||
foreach (var nested in juiceStream.NestedHitObjects)
|
||||
{
|
||||
@ -103,6 +105,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable
|
||||
double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth);
|
||||
float distanceToHyper = (float)(timeToNext * CatcherArea.Catcher.BASE_SPEED - distanceToNext);
|
||||
|
||||
if (distanceToHyper < 0)
|
||||
{
|
||||
currentObject.HyperDashTarget = nextObject;
|
||||
|
@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
new CatchModNoFail(),
|
||||
new MultiMod(new CatchModHalfTime(), new CatchModDaycore())
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -96,17 +97,20 @@ namespace osu.Game.Rulesets.Catch
|
||||
new CatchModHidden(),
|
||||
new CatchModFlashlight(),
|
||||
};
|
||||
|
||||
case ModType.Automation:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new CatchModAutoplay(), new ModCinema()),
|
||||
new CatchModRelax(),
|
||||
};
|
||||
|
||||
case ModType.Fun:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new ModWindUp<CatchHitObject>(), new ModWindDown<CatchHitObject>())
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
|
||||
lastObject = hitObject;
|
||||
break;
|
||||
|
||||
case JuiceStream _:
|
||||
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
|
||||
{
|
||||
|
@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 1100;
|
||||
}
|
||||
@ -27,8 +28,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 8;
|
||||
return 0.008;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 30;
|
||||
}
|
||||
@ -23,9 +24,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
switch (result)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
return base.HealthIncreaseFor(result);
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 7;
|
||||
return 0.007;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 300;
|
||||
}
|
||||
@ -27,9 +28,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
switch (result)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
return -0.02;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 10.2;
|
||||
return 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 10;
|
||||
}
|
||||
@ -26,8 +27,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 4;
|
||||
return 0.004;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut().Expire();
|
||||
break;
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||
@ -105,6 +106,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
default:
|
||||
return new Container();
|
||||
|
||||
case FruitVisualRepresentation.Raspberry:
|
||||
return new Container
|
||||
{
|
||||
@ -143,6 +145,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Pineapple:
|
||||
return new Container
|
||||
{
|
||||
@ -181,6 +184,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Pear:
|
||||
return new Container
|
||||
{
|
||||
@ -213,6 +217,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Grape:
|
||||
return new Container
|
||||
{
|
||||
@ -245,6 +250,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Banana:
|
||||
return new Container
|
||||
{
|
||||
@ -282,19 +288,25 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
default:
|
||||
case FruitVisualRepresentation.Pear:
|
||||
return new Color4(17, 136, 170, 255);
|
||||
|
||||
case FruitVisualRepresentation.Grape:
|
||||
return new Color4(204, 102, 0, 255);
|
||||
|
||||
case FruitVisualRepresentation.Raspberry:
|
||||
return new Color4(121, 9, 13, 255);
|
||||
|
||||
case FruitVisualRepresentation.Pineapple:
|
||||
return new Color4(102, 136, 0, 255);
|
||||
|
||||
case FruitVisualRepresentation.Banana:
|
||||
switch (RNG.Next(0, 3))
|
||||
{
|
||||
default:
|
||||
return new Color4(255, 240, 0, 255);
|
||||
|
||||
case 1:
|
||||
return new Color4(255, 192, 0, 255);
|
||||
|
||||
case 2:
|
||||
return new Color4(214, 221, 28, 255);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
@ -95,6 +95,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
|
||||
});
|
||||
break;
|
||||
|
||||
case SliderEventType.Head:
|
||||
case SliderEventType.Tail:
|
||||
case SliderEventType.Repeat:
|
||||
|
@ -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 System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
@ -27,20 +26,16 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
||||
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
|
||||
}
|
||||
|
||||
private const double harshness = 0.01;
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
||||
{
|
||||
base.ApplyResult(result);
|
||||
|
||||
if (result.Type == HitResult.Miss)
|
||||
switch (result.Type)
|
||||
{
|
||||
if (!result.Judgement.IsBonus)
|
||||
Health.Value -= hpDrainRate * (harshness * 2);
|
||||
return;
|
||||
}
|
||||
case HitResult.Miss:
|
||||
return hpDrainRate;
|
||||
|
||||
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
|
||||
default:
|
||||
return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
|
||||
}
|
||||
}
|
||||
|
||||
public override HitWindows CreateHitWindows() => new CatchHitWindows();
|
||||
|
@ -292,6 +292,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
const float hyper_dash_transition_length = 180;
|
||||
|
||||
bool previouslyHyperDashing = HyperDashing;
|
||||
|
||||
if (modifier <= 1 || X == targetPosition)
|
||||
{
|
||||
hyperDashModifier = 1;
|
||||
@ -325,9 +326,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
case CatchAction.MoveLeft:
|
||||
currentDirection--;
|
||||
return true;
|
||||
|
||||
case CatchAction.MoveRight:
|
||||
currentDirection++;
|
||||
return true;
|
||||
|
||||
case CatchAction.Dash:
|
||||
Dashing = true;
|
||||
return true;
|
||||
@ -343,9 +346,11 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
case CatchAction.MoveLeft:
|
||||
currentDirection++;
|
||||
return true;
|
||||
|
||||
case CatchAction.MoveRight:
|
||||
currentDirection--;
|
||||
return true;
|
||||
|
||||
case CatchAction.Dash:
|
||||
Dashing = false;
|
||||
return true;
|
||||
|
@ -48,14 +48,19 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
case Banana banana:
|
||||
return new DrawableBanana(banana);
|
||||
|
||||
case Fruit fruit:
|
||||
return new DrawableFruit(fruit);
|
||||
|
||||
case JuiceStream stream:
|
||||
return new DrawableJuiceStream(stream, CreateDrawableRepresentation);
|
||||
|
||||
case BananaShower shower:
|
||||
return new DrawableBananaShower(shower, CreateDrawableRepresentation);
|
||||
|
||||
case TinyDroplet tiny:
|
||||
return new DrawableTinyDroplet(tiny);
|
||||
|
||||
case Droplet droplet:
|
||||
return new DrawableDroplet(droplet);
|
||||
}
|
||||
|
@ -168,11 +168,13 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
foreach (var nested in obj.NestedHitObjects)
|
||||
{
|
||||
double finalPosition = (nested.HitObject.StartTime - obj.HitObject.StartTime) / endTime.Duration;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case ScrollingDirection.Up:
|
||||
nested.Y = (float)(finalPosition * content.DrawHeight);
|
||||
break;
|
||||
|
||||
case ScrollingDirection.Down:
|
||||
nested.Y = (float)(-finalPosition * content.DrawHeight);
|
||||
break;
|
||||
|
@ -48,6 +48,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
if (IsForCurrentRuleset)
|
||||
{
|
||||
TargetColumns = (int)Math.Max(1, roundedCircleSize);
|
||||
|
||||
if (TargetColumns >= 10)
|
||||
{
|
||||
TargetColumns = TargetColumns / 2;
|
||||
|
@ -179,6 +179,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
|
||||
int nextColumn = GetRandomColumn();
|
||||
|
||||
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
|
||||
{
|
||||
// Find available column
|
||||
@ -217,6 +218,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
|
||||
|
||||
int lastColumn = nextColumn;
|
||||
|
||||
for (int i = 0; i < noteCount; i++)
|
||||
{
|
||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||
@ -299,6 +301,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
|
||||
|
||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||
|
||||
for (int i = 0; i <= spanCount; i++)
|
||||
{
|
||||
addToPattern(pattern, nextColumn, startTime, startTime);
|
||||
@ -341,16 +344,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
p2 = Math.Min(p2, 0.1);
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p2 = Math.Min(p2, 0.3);
|
||||
p3 = Math.Min(p3, 0.04);
|
||||
p4 = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
p2 = Math.Min(p2, 0.34);
|
||||
p3 = Math.Min(p3, 0.1);
|
||||
@ -440,6 +446,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
||||
|
||||
var rowPattern = new Pattern();
|
||||
|
||||
for (int i = 0; i <= spanCount; i++)
|
||||
{
|
||||
if (!(ignoreHead && startTime == HitObject.StartTime))
|
||||
|
@ -38,9 +38,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
|
||||
addToPattern(pattern, 0, generateHold);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
addToPattern(pattern, FindAvailableColumn(GetRandomColumn(), PreviousPattern), generateHold);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (TotalColumns > 0)
|
||||
addToPattern(pattern, GetRandomColumn(), generateHold);
|
||||
|
@ -233,6 +233,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
||||
|
||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||
|
||||
for (int i = 0; i < noteCount; i++)
|
||||
{
|
||||
nextColumn = allowStacking
|
||||
@ -303,6 +304,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
int columnLimit = (TotalColumns % 2 == 0 ? TotalColumns : TotalColumns - 1) / 2;
|
||||
int nextColumn = GetRandomColumn(upperBound: columnLimit);
|
||||
|
||||
for (int i = 0; i < noteCount; i++)
|
||||
{
|
||||
nextColumn = FindAvailableColumn(nextColumn, upperBound: columnLimit, patterns: pattern);
|
||||
@ -340,18 +342,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
p4 = 0;
|
||||
p5 = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
p2 = Math.Min(p2, 0.1);
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
p5 = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
p2 = Math.Min(p2, 0.23);
|
||||
p3 = Math.Min(p3, 0.04);
|
||||
p4 = 0;
|
||||
p5 = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
p3 = Math.Min(p3, 0.15);
|
||||
p4 = Math.Min(p4, 0.03);
|
||||
@ -384,20 +389,24 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
p2 = 0;
|
||||
p3 = 0;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
centreProbability = Math.Min(centreProbability, 0.03);
|
||||
p2 = 0;
|
||||
p3 = 0;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
centreProbability = 0;
|
||||
p2 = Math.Min(p2 * 2, 0.2);
|
||||
p3 = 0;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
centreProbability = Math.Min(centreProbability, 0.03);
|
||||
p3 = 0;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
centreProbability = 0;
|
||||
p2 = Math.Min(p2 * 2, 0.5);
|
||||
|
@ -158,6 +158,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
|
||||
// Ensure that we have at least one free column, so that an endless loop is avoided
|
||||
bool hasValidColumns = false;
|
||||
|
||||
for (int i = lowerBound.Value; i < upperBound.Value; i++)
|
||||
{
|
||||
hasValidColumns = isValid(i);
|
||||
|
@ -66,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
case DrawableNote note:
|
||||
return new NoteSelectionBlueprint(note);
|
||||
|
||||
case DrawableHoldNote holdNote:
|
||||
return new HoldNoteSelectionBlueprint(holdNote);
|
||||
}
|
||||
|
@ -10,5 +10,17 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
||||
public override bool AffectsCombo => false;
|
||||
|
||||
protected override int NumericResultFor(HitResult result) => 20;
|
||||
|
||||
protected override double HealthIncreaseFor(HitResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0.040;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,47 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Meh:
|
||||
return 50;
|
||||
|
||||
case HitResult.Ok:
|
||||
return 100;
|
||||
|
||||
case HitResult.Good:
|
||||
return 200;
|
||||
|
||||
case HitResult.Great:
|
||||
case HitResult.Perfect:
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
|
||||
protected override double HealthIncreaseFor(HitResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return -0.125;
|
||||
|
||||
case HitResult.Meh:
|
||||
return 0.005;
|
||||
|
||||
case HitResult.Ok:
|
||||
return 0.010;
|
||||
|
||||
case HitResult.Good:
|
||||
return 0.035;
|
||||
|
||||
case HitResult.Great:
|
||||
return 0.055;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 0.065;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
new ManiaModNoFail(),
|
||||
new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()),
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -126,6 +127,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()),
|
||||
new ManiaModFlashlight(),
|
||||
};
|
||||
|
||||
case ModType.Conversion:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -142,16 +144,19 @@ namespace osu.Game.Rulesets.Mania
|
||||
new ManiaModDualStages(),
|
||||
new ManiaModMirror(),
|
||||
};
|
||||
|
||||
case ModType.Automation:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new ManiaModAutoplay(), new ModCinema()),
|
||||
};
|
||||
|
||||
case ModType.Fun:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new ModWindUp<ManiaHitObject>(), new ModWindDown<ManiaHitObject>())
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
@ -214,6 +219,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
SpecialAction = ManiaAction.Special1,
|
||||
NormalActionStart = ManiaAction.Key1,
|
||||
}.GenerateKeyBindingsFor(variant, out _);
|
||||
|
||||
case PlayfieldType.Dual:
|
||||
int keys = getDualStageKeyCount(variant);
|
||||
|
||||
@ -271,6 +277,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
default:
|
||||
return $"{variant}K";
|
||||
|
||||
case PlayfieldType.Dual:
|
||||
{
|
||||
var keys = getDualStageKeyCount(variant);
|
||||
|
@ -7,6 +7,7 @@ using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
|
@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(150, Easing.In).Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut(150, Easing.OutQuint).Expire();
|
||||
break;
|
||||
|
@ -5,7 +5,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
@ -7,6 +7,7 @@ using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
@ -144,6 +145,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
||||
const float animation_length = 50;
|
||||
|
||||
Foreground.ClearTransforms(false, nameof(Foreground.Colour));
|
||||
|
||||
if (hitting)
|
||||
{
|
||||
// wait for the next sync point
|
||||
|
@ -4,6 +4,7 @@
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osuTK.Graphics;
|
||||
|
@ -28,6 +28,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
var normalAction = ManiaAction.Key1;
|
||||
var specialAction = ManiaAction.Special1;
|
||||
int totalCounter = 0;
|
||||
|
||||
foreach (var stage in Beatmap.Stages)
|
||||
{
|
||||
for (int i = 0; i < stage.Columns; i++)
|
||||
@ -51,6 +52,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time);
|
||||
|
||||
var actions = new List<ManiaAction>();
|
||||
|
||||
foreach (var group in pointGroups)
|
||||
{
|
||||
foreach (var point in group)
|
||||
@ -60,6 +62,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
case HitPoint _:
|
||||
actions.Add(columnActions[point.Column]);
|
||||
break;
|
||||
|
||||
case ReleasePoint _:
|
||||
actions.Remove(columnActions[point.Column]);
|
||||
break;
|
||||
|
@ -39,6 +39,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
|
||||
int activeColumns = (int)(legacyFrame.MouseX ?? 0);
|
||||
int counter = 0;
|
||||
|
||||
while (activeColumns > 0)
|
||||
{
|
||||
var isSpecial = stage.IsSpecialColumn(counter);
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Judgements;
|
||||
using osu.Game.Rulesets.Mania.Objects;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
@ -28,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private const double hp_multiplier_max = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The default BAD hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_bad = 0.005;
|
||||
|
||||
/// <summary>
|
||||
/// The default OK hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_ok = 0.010;
|
||||
|
||||
/// <summary>
|
||||
/// The default GOOD hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_good = 0.035;
|
||||
|
||||
/// <summary>
|
||||
/// The default tick hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_tick = 0.040;
|
||||
|
||||
/// <summary>
|
||||
/// The default GREAT hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_great = 0.055;
|
||||
|
||||
/// <summary>
|
||||
/// The default PERFECT hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_perfect = 0.065;
|
||||
|
||||
/// <summary>
|
||||
/// The MISS HP multiplier at OD = 0.
|
||||
/// </summary>
|
||||
@ -73,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private const double hp_multiplier_miss_max = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The default MISS HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_miss = -0.125;
|
||||
|
||||
/// <summary>
|
||||
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
|
||||
/// </summary>
|
||||
@ -88,10 +52,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private double hpMultiplier = 1;
|
||||
|
||||
public ManiaScoreProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
{
|
||||
@ -122,42 +82,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
{
|
||||
base.ApplyResult(result);
|
||||
|
||||
bool isTick = result.Judgement is HoldNoteTickJudgement;
|
||||
|
||||
if (isTick)
|
||||
{
|
||||
if (result.IsHit)
|
||||
Health.Value += hpMultiplier * hp_increase_tick;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (result.Type)
|
||||
{
|
||||
case HitResult.Miss:
|
||||
Health.Value += hpMissMultiplier * hp_increase_miss;
|
||||
break;
|
||||
case HitResult.Meh:
|
||||
Health.Value += hpMultiplier * hp_increase_bad;
|
||||
break;
|
||||
case HitResult.Ok:
|
||||
Health.Value += hpMultiplier * hp_increase_ok;
|
||||
break;
|
||||
case HitResult.Good:
|
||||
Health.Value += hpMultiplier * hp_increase_good;
|
||||
break;
|
||||
case HitResult.Great:
|
||||
Health.Value += hpMultiplier * hp_increase_great;
|
||||
break;
|
||||
case HitResult.Perfect:
|
||||
Health.Value += hpMultiplier * hp_increase_perfect;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
||||
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
|
||||
|
||||
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Game.Graphics;
|
||||
|
@ -57,6 +57,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - point.BeatLength : lastObjectTime + point.BeatLength * (int)point.TimeSignature;
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++)
|
||||
{
|
||||
barLines.Add(new BarLine
|
||||
@ -105,8 +106,10 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
{
|
||||
case HoldNote holdNote:
|
||||
return new DrawableHoldNote(holdNote);
|
||||
|
||||
case Note note:
|
||||
return new DrawableNote(note);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.MathUtils;
|
||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||
|
@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
var normalColumnAction = ManiaAction.Key1;
|
||||
var specialColumnAction = ManiaAction.Special1;
|
||||
int firstColumnIndex = 0;
|
||||
|
||||
for (int i = 0; i < stageDefinitions.Count; i++)
|
||||
{
|
||||
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
|
||||
@ -92,6 +93,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
private ManiaStage getStageByColumn(int column)
|
||||
{
|
||||
int sum = 0;
|
||||
|
||||
foreach (var stage in stages)
|
||||
{
|
||||
sum = sum + stage.Columns.Count;
|
||||
|
@ -35,6 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
yield return createConvertValue(nested);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
yield return createConvertValue(hitObject);
|
||||
|
||||
|
@ -44,12 +44,14 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
if (endIndex < 0) throw new ArgumentOutOfRangeException(nameof(endIndex), $"{nameof(endIndex)} cannot be less than 0.");
|
||||
|
||||
int extendedEndIndex = endIndex;
|
||||
|
||||
if (endIndex < beatmap.HitObjects.Count - 1)
|
||||
{
|
||||
// Extend the end index to include objects they are stacked on
|
||||
for (int i = endIndex; i >= startIndex; i--)
|
||||
{
|
||||
int stackBaseIndex = i;
|
||||
|
||||
for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
|
||||
{
|
||||
OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
|
||||
@ -87,6 +89,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
|
||||
//Reverse pass for stack calculation.
|
||||
int extendedStartIndex = startIndex;
|
||||
|
||||
for (int i = extendedEndIndex; i > startIndex; i--)
|
||||
{
|
||||
int n = i;
|
||||
@ -138,6 +141,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
||||
if (objectN is Slider && Vector2Extensions.Distance(objectN.EndPosition, objectI.Position) < stack_distance)
|
||||
{
|
||||
int offset = objectI.StackHeight - objectN.StackHeight + 1;
|
||||
|
||||
for (int j = n + 1; j <= i; j++)
|
||||
{
|
||||
//For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
|
||||
|
@ -109,6 +109,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
||||
aimValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
|
||||
|
||||
double approachRateFactor = 1.0f;
|
||||
|
||||
if (Attributes.ApproachRate > 10.33f)
|
||||
approachRateFactor += 0.3f * (Attributes.ApproachRate - 10.33f);
|
||||
else if (Attributes.ApproachRate < 8.0f)
|
||||
|
@ -56,6 +56,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
{
|
||||
// We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps.
|
||||
float scalingFactor = normalized_radius / (float)BaseObject.Radius;
|
||||
|
||||
if (BaseObject.Radius < 30)
|
||||
{
|
||||
float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50;
|
||||
|
@ -42,9 +42,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||
speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2);
|
||||
|
||||
double angleBonus = 1.0;
|
||||
|
||||
if (osuCurrent.Angle != null && osuCurrent.Angle.Value < angle_bonus_begin)
|
||||
{
|
||||
angleBonus = 1 + Math.Pow(Math.Sin(1.5 * (angle_bonus_begin - osuCurrent.Angle.Value)), 2) / 3.57;
|
||||
|
||||
if (osuCurrent.Angle.Value < pi_over_2)
|
||||
{
|
||||
angleBonus = 1.28;
|
||||
|
@ -37,6 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
|
||||
case SliderPosition.Start:
|
||||
Position = slider.StackedPosition + slider.Path.PositionAt(0);
|
||||
break;
|
||||
|
||||
case SliderPosition.End:
|
||||
Position = slider.StackedPosition + slider.Path.PositionAt(1);
|
||||
break;
|
||||
|
@ -62,6 +62,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
case PlacementState.Initial:
|
||||
HitObject.Position = e.MousePosition;
|
||||
return true;
|
||||
|
||||
case PlacementState.Body:
|
||||
cursor = e.MousePosition - HitObject.Position;
|
||||
return true;
|
||||
@ -77,6 +78,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
case PlacementState.Initial:
|
||||
beginCurve();
|
||||
break;
|
||||
|
||||
case PlacementState.Body:
|
||||
switch (e.Button)
|
||||
{
|
||||
|
@ -42,8 +42,10 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
{
|
||||
case DrawableHitCircle circle:
|
||||
return new HitCircleSelectionBlueprint(circle);
|
||||
|
||||
case DrawableSlider slider:
|
||||
return new SliderSelectionBlueprint(slider);
|
||||
|
||||
case DrawableSpinner spinner:
|
||||
return new SpinnerSelectionBlueprint(spinner);
|
||||
}
|
||||
|
@ -16,13 +16,33 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Meh:
|
||||
return 50;
|
||||
|
||||
case HitResult.Good:
|
||||
return 100;
|
||||
|
||||
case HitResult.Great:
|
||||
return 300;
|
||||
}
|
||||
}
|
||||
|
||||
protected override double HealthIncreaseFor(HitResult result)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return -0.02;
|
||||
|
||||
case HitResult.Meh:
|
||||
case HitResult.Good:
|
||||
case HitResult.Great:
|
||||
return 0.01;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -41,6 +42,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
scoreProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); };
|
||||
}
|
||||
|
||||
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
||||
|
||||
/// <summary>
|
||||
/// Element for the Blinds mod drawing 2 black boxes covering the whole screen which resize inside a restricted area with some leniency.
|
||||
/// </summary>
|
||||
|
@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
{
|
||||
case DrawableSpinner _:
|
||||
continue;
|
||||
|
||||
default:
|
||||
drawable.ApplyCustomUpdateState += ApplyCustomState;
|
||||
break;
|
||||
@ -51,6 +52,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
case DrawableSliderTail _:
|
||||
// special cases we should *not* be scaling.
|
||||
break;
|
||||
|
||||
case DrawableSlider _:
|
||||
case DrawableHitCircle _:
|
||||
{
|
||||
|
@ -59,11 +59,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
circle.FadeOut(fadeOutDuration);
|
||||
|
||||
break;
|
||||
|
||||
case DrawableSlider slider:
|
||||
using (slider.BeginAbsoluteSequence(fadeOutStartTime, true))
|
||||
slider.Body.FadeOut(longFadeDuration, Easing.Out);
|
||||
|
||||
break;
|
||||
|
||||
case DrawableSliderTick sliderTick:
|
||||
// slider ticks fade out over up to one second
|
||||
var tickFadeOutDuration = Math.Min(sliderTick.HitObject.TimePreempt - DrawableSliderTick.ANIM_DURATION, 1000);
|
||||
@ -72,6 +74,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
sliderTick.FadeOut(tickFadeOutDuration);
|
||||
|
||||
break;
|
||||
|
||||
case DrawableSpinner spinner:
|
||||
// hide elements we don't care about.
|
||||
spinner.Disc.Hide();
|
||||
|
@ -6,6 +6,7 @@ using osuTK.Graphics;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Skinning;
|
||||
|
||||
|
@ -67,6 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
||||
return;
|
||||
|
||||
OsuHitObject prevHitObject = null;
|
||||
|
||||
foreach (var currHitObject in hitObjects)
|
||||
{
|
||||
if (prevHitObject != null && !currHitObject.NewCombo && !(prevHitObject is Spinner) && !(currHitObject is Spinner))
|
||||
|
@ -124,6 +124,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
}
|
||||
|
||||
var result = HitObject.HitWindows.ResultFor(timeOffset);
|
||||
|
||||
if (result == HitResult.None)
|
||||
{
|
||||
Shake(Math.Abs(timeOffset) - HitObject.HitWindows.HalfWindowFor(HitResult.Miss));
|
||||
@ -158,11 +159,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
// override lifetime end as FadeIn may have been changed externally, causing out expiration to be too early.
|
||||
LifetimeEnd = HitObject.StartTime + HitObject.HitWindows.HalfWindowFor(HitResult.Miss);
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
ApproachCircle.FadeOut(50);
|
||||
this.FadeOut(100);
|
||||
Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
ApproachCircle.FadeOut(50);
|
||||
|
||||
|
@ -64,9 +64,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
case ArmedState.Idle:
|
||||
this.Delay(HitObject.TimePreempt).FadeOut();
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(animDuration);
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut(animDuration, Easing.OutQuint)
|
||||
.ScaleTo(Scale * 1.5f, animDuration, Easing.Out);
|
||||
|
@ -67,10 +67,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
case ArmedState.Idle:
|
||||
this.Delay(HitObject.TimePreempt).FadeOut();
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(ANIM_DURATION);
|
||||
this.FadeColour(Color4.Red, ANIM_DURATION / 2);
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut(ANIM_DURATION, Easing.OutQuint);
|
||||
this.ScaleTo(Scale * 1.5f, ANIM_DURATION, Easing.Out);
|
||||
|
@ -222,9 +222,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
case ArmedState.Idle:
|
||||
Expire(true);
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
sequence.ScaleTo(Scale * 1.2f, 320, Easing.Out);
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
sequence.ScaleTo(Scale * 0.8f, 320, Easing.In);
|
||||
break;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
|
@ -4,6 +4,7 @@
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
|
@ -183,6 +183,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
Samples = sampleList
|
||||
});
|
||||
break;
|
||||
|
||||
case SliderEventType.Head:
|
||||
AddNested(HeadCircle = new SliderCircle
|
||||
{
|
||||
@ -194,6 +195,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
ComboIndex = ComboIndex,
|
||||
});
|
||||
break;
|
||||
|
||||
case SliderEventType.LegacyLastTick:
|
||||
// we need to use the LegacyLastTick here for compatibility reasons (difficulty).
|
||||
// it is *okay* to use this because the TailCircle is not used for any meaningful purpose in gameplay.
|
||||
@ -206,6 +208,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
||||
ComboIndex = ComboIndex,
|
||||
});
|
||||
break;
|
||||
|
||||
case SliderEventType.Repeat:
|
||||
AddNested(new RepeatPoint
|
||||
{
|
||||
|
@ -104,6 +104,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
new MultiMod(new OsuModHalfTime(), new OsuModDaycore()),
|
||||
new OsuModSpunOut(),
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -113,11 +114,13 @@ namespace osu.Game.Rulesets.Osu
|
||||
new OsuModHidden(),
|
||||
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
||||
};
|
||||
|
||||
case ModType.Conversion:
|
||||
return new Mod[]
|
||||
{
|
||||
new OsuModTarget(),
|
||||
};
|
||||
|
||||
case ModType.Automation:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -125,6 +128,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
new OsuModRelax(),
|
||||
new OsuModAutopilot(),
|
||||
};
|
||||
|
||||
case ModType.Fun:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -133,6 +137,7 @@ namespace osu.Game.Rulesets.Osu
|
||||
new OsuModGrow(),
|
||||
new MultiMod(new ModWindUp<OsuHitObject>(), new ModWindDown<OsuHitObject>()),
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
|
||||
// Wait until Auto could "see and react" to the next note.
|
||||
double waitTime = h.StartTime - Math.Max(0.0, h.TimePreempt - reactionTime);
|
||||
|
||||
if (waitTime > lastFrame.Time)
|
||||
{
|
||||
lastFrame = new OsuReplayFrame(waitTime, lastFrame.Position) { Actions = lastFrame.Actions };
|
||||
@ -314,6 +315,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
||||
|
||||
endFrame.Position = endPosition;
|
||||
break;
|
||||
|
||||
case Slider slider:
|
||||
for (double j = FrameDelay; j < slider.Duration; j += FrameDelay)
|
||||
{
|
||||
|
@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
comboResultCounts.Clear();
|
||||
}
|
||||
|
||||
private const double harshness = 0.01;
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
{
|
||||
base.ApplyResult(result);
|
||||
@ -47,28 +45,29 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
||||
|
||||
if (result.Type != HitResult.None)
|
||||
comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1;
|
||||
}
|
||||
|
||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
||||
{
|
||||
switch (result.Type)
|
||||
{
|
||||
case HitResult.Great:
|
||||
Health.Value += (10.2 - hpDrainRate) * harshness;
|
||||
break;
|
||||
return 10.2 - hpDrainRate;
|
||||
|
||||
case HitResult.Good:
|
||||
Health.Value += (8 - hpDrainRate) * harshness;
|
||||
break;
|
||||
return 8 - hpDrainRate;
|
||||
|
||||
case HitResult.Meh:
|
||||
Health.Value += (4 - hpDrainRate) * harshness;
|
||||
break;
|
||||
return 4 - hpDrainRate;
|
||||
|
||||
/*case HitResult.SliderTick:
|
||||
Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01;
|
||||
break;*/
|
||||
// case HitResult.SliderTick:
|
||||
// return Math.Max(7 - hpDrainRate, 0) * 0.01;
|
||||
|
||||
case HitResult.Miss:
|
||||
Health.Value -= hpDrainRate * (harshness * 2);
|
||||
break;
|
||||
return hpDrainRate;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,22 +43,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
|
||||
private readonly InputResampler resampler = new InputResampler();
|
||||
|
||||
protected override DrawNode CreateDrawNode() => new TrailDrawNode();
|
||||
|
||||
protected override void ApplyDrawNode(DrawNode node)
|
||||
{
|
||||
base.ApplyDrawNode(node);
|
||||
|
||||
TrailDrawNode tNode = (TrailDrawNode)node;
|
||||
tNode.Shader = shader;
|
||||
tNode.Texture = texture;
|
||||
tNode.Size = size;
|
||||
tNode.Time = time;
|
||||
|
||||
for (int i = 0; i < parts.Length; ++i)
|
||||
if (parts[i].InvalidationID > tNode.Parts[i].InvalidationID)
|
||||
tNode.Parts[i] = parts[i];
|
||||
}
|
||||
protected override DrawNode CreateDrawNode() => new TrailDrawNode(this);
|
||||
|
||||
public CursorTrail()
|
||||
{
|
||||
@ -167,33 +152,53 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
|
||||
private class TrailDrawNode : DrawNode
|
||||
{
|
||||
public IShader Shader;
|
||||
public Texture Texture;
|
||||
protected new CursorTrail Source => (CursorTrail)base.Source;
|
||||
|
||||
public float Time;
|
||||
private IShader shader;
|
||||
private Texture texture;
|
||||
|
||||
public readonly TrailPart[] Parts = new TrailPart[max_sprites];
|
||||
public Vector2 Size;
|
||||
private float time;
|
||||
|
||||
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
||||
private Vector2 size;
|
||||
|
||||
private readonly VertexBuffer<TexturedTrailVertex> vertexBuffer = new QuadVertexBuffer<TexturedTrailVertex>(max_sprites, BufferUsageHint.DynamicDraw);
|
||||
|
||||
public TrailDrawNode()
|
||||
public TrailDrawNode(CursorTrail source)
|
||||
: base(source)
|
||||
{
|
||||
for (int i = 0; i < max_sprites; i++)
|
||||
{
|
||||
Parts[i].InvalidationID = 0;
|
||||
Parts[i].WasUpdated = false;
|
||||
parts[i].InvalidationID = 0;
|
||||
parts[i].WasUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ApplyState()
|
||||
{
|
||||
base.ApplyState();
|
||||
|
||||
shader = Source.shader;
|
||||
texture = Source.texture;
|
||||
size = Source.size;
|
||||
time = Source.time;
|
||||
|
||||
for (int i = 0; i < Source.parts.Length; ++i)
|
||||
{
|
||||
if (Source.parts[i].InvalidationID > parts[i].InvalidationID)
|
||||
parts[i] = Source.parts[i];
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw(Action<TexturedVertex2D> vertexAction)
|
||||
{
|
||||
Shader.GetUniform<float>("g_FadeClock").UpdateValue(ref Time);
|
||||
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time);
|
||||
|
||||
int updateStart = -1, updateEnd = 0;
|
||||
for (int i = 0; i < Parts.Length; ++i)
|
||||
|
||||
for (int i = 0; i < parts.Length; ++i)
|
||||
{
|
||||
if (Parts[i].WasUpdated)
|
||||
if (parts[i].WasUpdated)
|
||||
{
|
||||
if (updateStart == -1)
|
||||
updateStart = i;
|
||||
@ -202,22 +207,22 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
int start = i * 4;
|
||||
int end = start;
|
||||
|
||||
Vector2 pos = Parts[i].Position;
|
||||
float time = Parts[i].Time;
|
||||
Vector2 pos = parts[i].Position;
|
||||
float localTime = parts[i].Time;
|
||||
|
||||
Texture.DrawQuad(
|
||||
new Quad(pos.X - Size.X / 2, pos.Y - Size.Y / 2, Size.X, Size.Y),
|
||||
texture.DrawQuad(
|
||||
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
|
||||
DrawColourInfo.Colour,
|
||||
null,
|
||||
v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex
|
||||
{
|
||||
Position = v.Position,
|
||||
TexturePosition = v.TexturePosition,
|
||||
Time = time + 1,
|
||||
Time = localTime + 1,
|
||||
Colour = v.Colour,
|
||||
});
|
||||
|
||||
Parts[i].WasUpdated = false;
|
||||
parts[i].WasUpdated = false;
|
||||
}
|
||||
else if (updateStart != -1)
|
||||
{
|
||||
@ -232,12 +237,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
||||
|
||||
base.Draw(vertexAction);
|
||||
|
||||
Shader.Bind();
|
||||
shader.Bind();
|
||||
|
||||
Texture.TextureGL.Bind();
|
||||
texture.TextureGL.Bind();
|
||||
vertexBuffer.Draw();
|
||||
|
||||
Shader.Unbind();
|
||||
shader.Unbind();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
|
@ -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 System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Input;
|
||||
@ -45,8 +46,10 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
case HitCircle circle:
|
||||
return new DrawableHitCircle(circle);
|
||||
|
||||
case Slider slider:
|
||||
return new DrawableSlider(slider);
|
||||
|
||||
case Spinner spinner:
|
||||
return new DrawableSpinner(spinner);
|
||||
}
|
||||
@ -61,7 +64,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
get
|
||||
{
|
||||
var first = (OsuHitObject)Objects.First();
|
||||
return first.StartTime - first.TimePreempt;
|
||||
return first.StartTime - Math.Max(2000, first.TimePreempt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,15 +101,19 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
case 1:
|
||||
addCentreHit(false);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
addCentreHit(true);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
addDrumRoll(false);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
addDrumRoll(true);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
addSwell();
|
||||
delay = scroll_time - 100;
|
||||
@ -122,6 +126,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
default:
|
||||
playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, rng.Next(25, 400)), 500);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
playfieldContainer.Delay(delay).ResizeTo(new Vector2(1, TaikoPlayfield.DEFAULT_HEIGHT), 500);
|
||||
break;
|
||||
|
@ -120,6 +120,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
||||
List<List<SampleInfo>> allSamples = curveData != null ? curveData.NodeSamples : new List<List<SampleInfo>>(new[] { samples });
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
|
||||
{
|
||||
List<SampleInfo> currentSamples = allSamples[i];
|
||||
|
@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return base.HealthIncreaseFor(result);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Great:
|
||||
return 200;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -26,6 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Great:
|
||||
return 0.15;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,8 +16,10 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Good:
|
||||
return 100;
|
||||
|
||||
case HitResult.Great:
|
||||
return 300;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -29,10 +31,13 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return -1.0;
|
||||
|
||||
case HitResult.Good:
|
||||
return 1.1;
|
||||
|
||||
case HitResult.Great:
|
||||
return 3.0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Judgements
|
||||
{
|
||||
case HitResult.Miss:
|
||||
return -0.65;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
circlePiece?.FlashBox.FinishTransforms();
|
||||
|
||||
var offset = !AllJudged ? 0 : Time.Current - HitObject.StartTime;
|
||||
|
||||
using (BeginDelayedSequence(HitObject.StartTime - Time.Current + offset, true))
|
||||
{
|
||||
switch (State.Value)
|
||||
@ -108,15 +109,18 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
UnproxyContent();
|
||||
this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(100)
|
||||
.Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
// If we're far enough away from the left stage, we should bring outselves in front of it
|
||||
ProxyContent();
|
||||
|
||||
var flash = circlePiece?.FlashBox;
|
||||
|
||||
if (flash != null)
|
||||
{
|
||||
flash.FadeTo(0.9f);
|
||||
|
@ -192,6 +192,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
using (BeginAbsoluteSequence(HitObject.StartTime - preempt, true))
|
||||
targetRing.ScaleTo(target_ring_scale, preempt * 4, Easing.OutQuint);
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut(out_transition_time, Easing.Out);
|
||||
|
@ -111,6 +111,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
MainPiece.KiaiMode = HitObject.Kiai;
|
||||
|
||||
var strongObject = HitObject.NestedHitObjects.OfType<StrongHitObject>().FirstOrDefault();
|
||||
|
||||
if (strongObject != null)
|
||||
{
|
||||
var strongHit = CreateStrongHit(strongObject);
|
||||
|
@ -9,6 +9,7 @@ using osu.Game.Graphics.Backgrounds;
|
||||
using osuTK.Graphics;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
|
||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces
|
||||
{
|
||||
|
@ -70,6 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
return;
|
||||
|
||||
bool first = true;
|
||||
|
||||
for (double t = StartTime; t < EndTime + tickSpacing / 2; t += tickSpacing)
|
||||
{
|
||||
AddNested(new DrumRollTick
|
||||
|
@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
||||
case HitResult.Good:
|
||||
case HitResult.Miss:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
int count = 0;
|
||||
int req = swell.RequiredHits;
|
||||
double hitRate = Math.Min(swell_hit_speed, swell.Duration / req);
|
||||
|
||||
for (double j = h.StartTime; j < endTime; j += hitRate)
|
||||
{
|
||||
TaikoAction action;
|
||||
@ -62,12 +63,15 @@ namespace osu.Game.Rulesets.Taiko.Replays
|
||||
case 0:
|
||||
action = TaikoAction.LeftCentre;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
action = TaikoAction.LeftRim;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
action = TaikoAction.RightCentre;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
action = TaikoAction.RightRim;
|
||||
break;
|
||||
|
@ -46,19 +46,8 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
|
||||
}
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
{
|
||||
base.ApplyResult(result);
|
||||
|
||||
double hpIncrease = result.Judgement.HealthIncreaseFor(result);
|
||||
|
||||
if (result.Type == HitResult.Miss)
|
||||
hpIncrease *= hpMissMultiplier;
|
||||
else
|
||||
hpIncrease *= hpMultiplier;
|
||||
|
||||
Health.Value += hpIncrease;
|
||||
}
|
||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
||||
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
{
|
||||
|
@ -86,6 +86,7 @@ namespace osu.Game.Rulesets.Taiko
|
||||
new TaikoModNoFail(),
|
||||
new MultiMod(new TaikoModHalfTime(), new TaikoModDaycore()),
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@ -95,17 +96,20 @@ namespace osu.Game.Rulesets.Taiko
|
||||
new TaikoModHidden(),
|
||||
new TaikoModFlashlight(),
|
||||
};
|
||||
|
||||
case ModType.Automation:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new TaikoModAutoplay(), new ModCinema()),
|
||||
new TaikoModRelax(),
|
||||
};
|
||||
|
||||
case ModType.Fun:
|
||||
return new Mod[]
|
||||
{
|
||||
new MultiMod(new ModWindUp<TaikoHitObject>(), new ModWindDown<TaikoHitObject>())
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
case HitResult.Good:
|
||||
JudgementBody.Colour = colours.GreenLight;
|
||||
break;
|
||||
|
||||
case HitResult.Great:
|
||||
JudgementBody.Colour = colours.BlueLight;
|
||||
break;
|
||||
|
@ -54,9 +54,11 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
int currentIndex = 0;
|
||||
int currentBeat = 0;
|
||||
double time = timingPoints[currentIndex].Time;
|
||||
|
||||
while (time <= lastHitTime)
|
||||
{
|
||||
int nextIndex = currentIndex + 1;
|
||||
|
||||
if (nextIndex < timingPoints.Count && time > timingPoints[nextIndex].Time)
|
||||
{
|
||||
currentIndex = nextIndex;
|
||||
@ -95,10 +97,13 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
{
|
||||
case CentreHit centreHit:
|
||||
return new DrawableCentreHit(centreHit);
|
||||
|
||||
case RimHit rimHit:
|
||||
return new DrawableRimHit(rimHit);
|
||||
|
||||
case DrumRoll drumRoll:
|
||||
return new DrawableDrumRoll(drumRoll);
|
||||
|
||||
case Swell swell:
|
||||
return new DrawableSwell(swell);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using osuTK;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
|
@ -6,6 +6,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Graphics;
|
||||
@ -211,6 +212,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
case DrawableBarLine barline:
|
||||
barlineContainer.Add(barline.CreateProxy());
|
||||
break;
|
||||
|
||||
case DrawableTaikoHitObject taikoObject:
|
||||
topLevelHitContainer.Add(taikoObject.CreateProxiedContent());
|
||||
break;
|
||||
@ -231,6 +233,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
if (result.IsHit)
|
||||
hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).MainObject)?.VisualiseSecondHit();
|
||||
break;
|
||||
|
||||
default:
|
||||
judgementContainer.Add(new DrawableTaikoJudgement(result, judgedObject)
|
||||
{
|
||||
|
@ -49,6 +49,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapGeneral()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -72,6 +73,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapEditor()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -97,6 +99,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapMetadata()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -121,6 +124,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapDifficulty()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -139,6 +143,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapEvents()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -157,6 +162,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapTimingPoints()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -192,6 +198,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapColours()
|
||||
{
|
||||
var decoder = new LegacySkinDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -217,6 +224,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapComboOffsetsOsu()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("hitobject-combo-offset.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -239,6 +247,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapComboOffsetsCatch()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("hitobject-combo-offset.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -261,6 +270,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeBeatmapHitObjects()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -288,6 +298,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeControlPointCustomSampleBank()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("controlpoint-custom-samplebank.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -309,6 +320,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeHitObjectCustomSampleBank()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("hitobject-custom-samplebank.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -326,6 +338,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeHitObjectFileSamples()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("hitobject-file-samples.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -345,6 +358,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeSliderSamples()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("slider-samples.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -388,6 +402,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeHitObjectNullAdditionBank()
|
||||
{
|
||||
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||
|
||||
using (var resStream = TestResources.OpenResource("hitobject-no-addition-bank.osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
|
@ -19,6 +19,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeStoryboardEvents()
|
||||
{
|
||||
var decoder = new LegacyStoryboardDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("Himeringo - Yotsuya-san ni Yoroshiku (RLC) [Winber1's Extreme].osu"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
@ -91,6 +92,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
public void TestDecodeVariableWithSuffix()
|
||||
{
|
||||
var decoder = new LegacyStoryboardDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource("variable-with-suffix.osb"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
|
@ -151,6 +151,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
||||
using (var sr = new StreamReader(stream))
|
||||
{
|
||||
var legacyDecoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.Decode(sr);
|
||||
|
||||
using (var ms = new MemoryStream())
|
||||
using (var sw = new StreamWriter(ms))
|
||||
using (var sr2 = new StreamReader(ms))
|
||||
|
@ -75,6 +75,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
||||
using (var osz = TestResources.GetTestBeatmapStream())
|
||||
{
|
||||
var reader = new ZipArchiveReader(osz);
|
||||
|
||||
using (var stream = new StreamReader(
|
||||
reader.GetStream("Soleily - Renatus (Deif) [Platter].osu")))
|
||||
{
|
||||
|
@ -18,6 +18,7 @@ namespace osu.Game.Tests.Skins
|
||||
public void TestDecodeSkinColours(bool hasColours)
|
||||
{
|
||||
var decoder = new LegacySkinDecoder();
|
||||
|
||||
using (var resStream = TestResources.OpenResource(hasColours ? "skin.ini" : "skin-empty.ini"))
|
||||
using (var stream = new StreamReader(resStream))
|
||||
{
|
||||
|
@ -3,12 +3,13 @@
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Editor
|
||||
@ -16,35 +17,38 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
[TestFixture]
|
||||
public class TestCaseWaveform : OsuTestCase
|
||||
{
|
||||
private WorkingBeatmap waveformBeatmap;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Beatmap.Value = new WaveformTestBeatmap();
|
||||
waveformBeatmap = new WaveformTestBeatmap();
|
||||
}
|
||||
|
||||
FillFlowContainer flow;
|
||||
Child = flow = new FillFlowContainer
|
||||
[TestCase(1f)]
|
||||
[TestCase(1f / 2)]
|
||||
[TestCase(1f / 4)]
|
||||
[TestCase(1f / 8)]
|
||||
[TestCase(1f / 16)]
|
||||
[TestCase(0f)]
|
||||
public void TestResolution(float resolution)
|
||||
{
|
||||
TestWaveformGraph graph = null;
|
||||
|
||||
AddStep("add graph", () =>
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 10),
|
||||
};
|
||||
|
||||
for (int i = 1; i <= 16; i *= 2)
|
||||
{
|
||||
var newDisplay = new WaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Resolution = 1f / i,
|
||||
Waveform = Beatmap.Value.Waveform,
|
||||
};
|
||||
|
||||
flow.Add(new Container
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
newDisplay,
|
||||
graph = new TestWaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Resolution = resolution,
|
||||
Waveform = waveformBeatmap.Waveform,
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
@ -62,13 +66,42 @@ namespace osu.Game.Tests.Visual.Editor
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Text = $"Resolution: {1f / i:0.00}"
|
||||
Text = $"Resolution: {resolution:0.00}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for load", () => graph.ResampledWaveform != null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDefaultBeatmap()
|
||||
{
|
||||
TestWaveformGraph graph = null;
|
||||
|
||||
AddStep("add graph", () =>
|
||||
{
|
||||
Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 100,
|
||||
Child = graph = new TestWaveformGraph
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Waveform = new DummyWorkingBeatmap().Waveform,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
AddUntilStep("wait for load", () => graph.ResampledWaveform != null);
|
||||
}
|
||||
|
||||
public class TestWaveformGraph : WaveformGraph
|
||||
{
|
||||
public new Waveform ResampledWaveform => base.ResampledWaveform;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,150 @@
|
||||
// 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 NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Rulesets.UI;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestCaseFrameStabilityContainer : OsuTestCase
|
||||
{
|
||||
private readonly ManualClock manualClock;
|
||||
|
||||
private readonly Container mainContainer;
|
||||
|
||||
private ClockConsumingChild consumer;
|
||||
|
||||
public TestCaseFrameStabilityContainer()
|
||||
{
|
||||
Child = mainContainer = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Clock = new FramedClock(manualClock = new ManualClock()),
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLargeJumps()
|
||||
{
|
||||
seekManualTo(0);
|
||||
createStabilityContainer();
|
||||
seekManualTo(100000);
|
||||
|
||||
confirmSeek(100000);
|
||||
checkFrameCount(6000);
|
||||
|
||||
seekManualTo(0);
|
||||
|
||||
confirmSeek(0);
|
||||
checkFrameCount(12000);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSmallJumps()
|
||||
{
|
||||
seekManualTo(0);
|
||||
createStabilityContainer();
|
||||
seekManualTo(40);
|
||||
|
||||
confirmSeek(40);
|
||||
checkFrameCount(3);
|
||||
|
||||
seekManualTo(0);
|
||||
|
||||
confirmSeek(0);
|
||||
checkFrameCount(6);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSingleFrameJump()
|
||||
{
|
||||
seekManualTo(0);
|
||||
createStabilityContainer();
|
||||
seekManualTo(8);
|
||||
confirmSeek(8);
|
||||
checkFrameCount(1);
|
||||
|
||||
seekManualTo(16);
|
||||
confirmSeek(16);
|
||||
checkFrameCount(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestInitialSeek()
|
||||
{
|
||||
seekManualTo(100000);
|
||||
createStabilityContainer();
|
||||
|
||||
confirmSeek(100000);
|
||||
checkFrameCount(0);
|
||||
}
|
||||
|
||||
private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild()));
|
||||
|
||||
private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time);
|
||||
|
||||
private void confirmSeek(double time) => AddUntilStep($"wait for seek to {time}", () => consumer.Clock.CurrentTime == time);
|
||||
|
||||
private void checkFrameCount(int frames) =>
|
||||
AddAssert($"elapsed frames is {frames}", () => consumer.ElapsedFrames == frames);
|
||||
|
||||
public class ClockConsumingChild : CompositeDrawable
|
||||
{
|
||||
private readonly OsuSpriteText text;
|
||||
private readonly OsuSpriteText text2;
|
||||
private readonly OsuSpriteText text3;
|
||||
|
||||
public ClockConsumingChild()
|
||||
{
|
||||
Anchor = Anchor.Centre;
|
||||
Origin = Anchor.Centre;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
text = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
text2 = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
text3 = new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public int ElapsedFrames;
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if (Clock.ElapsedFrameTime != 0)
|
||||
ElapsedFrames++;
|
||||
|
||||
text.Text = $"current time: {Clock.CurrentTime:F0}";
|
||||
if (Clock.ElapsedFrameTime != 0)
|
||||
text2.Text = $"last elapsed frame time: {Clock.ElapsedFrameTime:F0}";
|
||||
text3.Text = $"total frames: {ElapsedFrames:F0}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -196,9 +196,10 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
public bool PauseOverlayVisible => PauseOverlay.State == Visibility.Visible;
|
||||
|
||||
public PausePlayer()
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
PauseOnFocusLost = false;
|
||||
base.LoadComplete();
|
||||
HUDOverlay.HoldToQuit.PauseOnFocusLost = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,21 +10,26 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public class TestCasePlayerLoader : ManualInputManagerTestCase
|
||||
{
|
||||
private PlayerLoader loader;
|
||||
private readonly OsuScreenStack stack;
|
||||
private OsuScreenStack stack;
|
||||
|
||||
public TestCasePlayerLoader()
|
||||
[SetUp]
|
||||
public void Setup() => Schedule(() =>
|
||||
{
|
||||
InputManager.Add(stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both });
|
||||
}
|
||||
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
|
||||
Beatmap.Value = new TestWorkingBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), Clock);
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestLoadContinuation()
|
||||
@ -33,8 +38,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
|
||||
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
|
||||
AddStep("exit loader", () => loader.Exit());
|
||||
AddUntilStep("wait for no longer alive", () => !loader.IsAlive);
|
||||
AddStep("load slow dummy beatmap", () =>
|
||||
{
|
||||
SlowLoadPlayer slow = null;
|
||||
@ -58,41 +61,25 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddStep("load player", () =>
|
||||
{
|
||||
Mods.Value = new[] { gameMod = new TestMod() };
|
||||
InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre);
|
||||
stack.Push(new PlayerLoader(() => player = new TestPlayer()));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for player to become current", () =>
|
||||
{
|
||||
if (player.IsCurrentScreen())
|
||||
{
|
||||
playerMod1 = (TestMod)player.Mods.Value.Single();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
stack.Push(loader = new PlayerLoader(() => player = new TestPlayer()));
|
||||
});
|
||||
|
||||
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
|
||||
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
|
||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
|
||||
AddStep("retrieve mods", () => playerMod1 = (TestMod)player.Mods.Value.Single());
|
||||
AddAssert("game mods not applied", () => gameMod.Applied == false);
|
||||
AddAssert("player mods applied", () => playerMod1.Applied);
|
||||
|
||||
AddStep("restart player", () =>
|
||||
{
|
||||
var lastPlayer = player;
|
||||
player = null;
|
||||
player.Restart();
|
||||
});
|
||||
|
||||
AddUntilStep("wait for player to become current", () =>
|
||||
{
|
||||
if (player.IsCurrentScreen())
|
||||
{
|
||||
playerMod2 = (TestMod)player.Mods.Value.Single();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
lastPlayer.Restart();
|
||||
});
|
||||
|
||||
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
|
||||
AddStep("retrieve mods", () => playerMod2 = (TestMod)player.Mods.Value.Single());
|
||||
AddAssert("game mods not applied", () => gameMod.Applied == false);
|
||||
AddAssert("player has different mods", () => playerMod1 != playerMod2);
|
||||
AddAssert("player mods applied", () => playerMod2.Applied);
|
||||
@ -110,6 +97,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
Applied = true;
|
||||
}
|
||||
|
||||
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
||||
}
|
||||
|
||||
private class TestPlayer : Player
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user